diff --git a/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java b/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java index b33093c..09127a7 100644 --- a/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java +++ b/src/main/java/com/ClubAccount_BE/core/config/SecurityConfig.java @@ -49,7 +49,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { API_V1_PREFIX + "/auth/reset-password", API_V1_PREFIX + "/{link}/receipts", API_V1_PREFIX + "/{link}/receipts/{receiptId}", - API_V1_PREFIX + "/{link}/receipts/category", + API_V1_PREFIX + "/{link}/receipts/category-expense", + API_V1_PREFIX + "/{link}/receipts/monthly-expense", "/api-docs", "/swagger-custom-ui.html", "/v3/api-docs", diff --git a/src/main/java/com/ClubAccount_BE/core/config/WebConfig.java b/src/main/java/com/ClubAccount_BE/core/config/WebConfig.java index 7d19f84..cd8e7e3 100644 --- a/src/main/java/com/ClubAccount_BE/core/config/WebConfig.java +++ b/src/main/java/com/ClubAccount_BE/core/config/WebConfig.java @@ -1,12 +1,12 @@ package com.ClubAccount_BE.core.config; import com.ClubAccount_BE.core.config.auth.LoginUserArgumentResolver; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import java.util.List; @RequiredArgsConstructor @Configuration @@ -22,7 +22,11 @@ public void addArgumentResolvers(List resolvers) @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") - .allowedOrigins("http://localhost:5173", "http://172.20.10.3:5173") + .allowedOrigins( + "http://localhost:5173", + "http://172.20.10.3:5173", + "https://club-account-fe.vercel.app" + ) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH") .allowedHeaders("*") .exposedHeaders("Authorization", "Set-Cookie") diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java index 7cb53fb..cf698ff 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java +++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/FindReceiptController.java @@ -2,9 +2,9 @@ import com.ClubAccount_BE.core.response.PagingResponse; import com.ClubAccount_BE.receipt.adapter.in.web.api.FindReceiptApi; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryResponse; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptExpenseResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptItemResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptMonthlyExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptResponse; import com.ClubAccount_BE.receipt.application.port.in.FindReceiptUseCase; import jakarta.validation.constraints.Positive; @@ -47,18 +47,18 @@ public List getReceiptItem( return findReceiptUseCase.getReceiptItem(link, receiptId); } - @GetMapping("/{link}/receipts/category") - public ReceiptCategoryResponse getReceiptCategoryRatio( + @GetMapping("/{link}/receipts/category-expense") + public ReceiptCategoryExpenseResponse getReceiptCategoryExpense( @PathVariable(value = "link") UUID link ) { - return findReceiptUseCase.getReceiptCategoryRatio(link); + return findReceiptUseCase.getReceiptCategoryExpense(link); } - @GetMapping("/{link}/receipts/expense") - public List getReceiptExpenseList( + @GetMapping("/{link}/receipts/monthly-expense") + public List getReceiptMonthlyExpenseList( @PathVariable(value = "link") UUID link, @Positive(message = "유효하지 않은 연도입니다.") @RequestParam int year ) { - return findReceiptUseCase.getReceiptExpenseList(link, year); + return findReceiptUseCase.getReceiptMonthlyExpenseList(link, year); } } diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java index 29645e2..2f6cea8 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java +++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/api/FindReceiptApi.java @@ -1,9 +1,9 @@ package com.ClubAccount_BE.receipt.adapter.in.web.api; import com.ClubAccount_BE.core.response.PagingResponse; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryResponse; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptExpenseResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptItemResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptMonthlyExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -38,13 +38,13 @@ List getReceiptItem( @PathVariable("receiptId") Long receiptId ); - @Operation(summary = "영수증 카테고리 비율 조회", description = "등록된 영수증의 카테고리 비율을 조회한다.") - ReceiptCategoryResponse getReceiptCategoryRatio( + @Operation(summary = "영수증 카테고리별 지출 조회", description = "등록된 영수증의 카테고리별 지출을 조회한다.") + ReceiptCategoryExpenseResponse getReceiptCategoryExpense( @PathVariable(value = "link") UUID link ); @Operation(summary = "영수증 월별 지출 목록 조회", description = "등록된 영수증의 월별 지출을 조회한다.") - List getReceiptExpenseList( + List getReceiptMonthlyExpenseList( @PathVariable(value = "link") UUID link, @Positive(message = "유효하지 않은 연도입니다.") @RequestParam int year ); diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptCategoryExpenseResponse.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptCategoryExpenseResponse.java new file mode 100644 index 0000000..57e2449 --- /dev/null +++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptCategoryExpenseResponse.java @@ -0,0 +1,36 @@ +package com.ClubAccount_BE.receipt.adapter.in.web.dto.response; + +import com.ClubAccount_BE.receipt.domain.ReceiptCategoryExpenseResult; +import io.swagger.v3.oas.annotations.media.Schema; +import java.math.BigDecimal; +import lombok.Builder; + +@Builder +public record ReceiptCategoryExpenseResponse( + @Schema(description = "회식비 카테고리 총 지출") + BigDecimal groupDiningExpense, + + @Schema(description = "물품 구매비 카테고리 총 지출") + BigDecimal supplyPurchaseExpense, + + @Schema(description = "정기 구독비 카테고리 총 지출") + BigDecimal subscriptionExpense, + + @Schema(description = "대관비 카테고리 총 지출") + BigDecimal venueRentalExpense, + + @Schema(description = "기타 카테고리 총 지출") + BigDecimal otherExpense +) { + + public static ReceiptCategoryExpenseResponse of(ReceiptCategoryExpenseResult result) { + return ReceiptCategoryExpenseResponse.builder() + .groupDiningExpense(result.getGroupDiningExpense()) + .supplyPurchaseExpense(result.getSupplyPurchaseExpense()) + .subscriptionExpense(result.getSubscriptionExpense()) + .venueRentalExpense(result.getVenueRentalExpense()) + .otherExpense(result.getOtherExpense()) + .build(); + } + +} diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptCategoryResponse.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptCategoryResponse.java deleted file mode 100644 index 7f4cf69..0000000 --- a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptCategoryResponse.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.ClubAccount_BE.receipt.adapter.in.web.dto.response; - -import com.ClubAccount_BE.receipt.domain.DetailCategoryResult; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; - -@Builder -public record ReceiptCategoryResponse( - @Schema(description = "회식비 비율") - float groupDiningRatio, - - @Schema(description = "물품 구매비 비율") - float supplyPurchaseRatio, - - @Schema(description = "정기 구독비 비율") - float subscriptionRatio, - - @Schema(description = "대관비 비율") - float venueRentalRatio, - - @Schema(description = "기타 비율") - float otherRatio -) { - - public static ReceiptCategoryResponse of(DetailCategoryResult result) { - return ReceiptCategoryResponse.builder() - .groupDiningRatio(result.getGroupDiningRatio()) - .supplyPurchaseRatio(result.getSupplyPurchaseRatio()) - .subscriptionRatio(result.getSubscriptionRatio()) - .venueRentalRatio(result.getVenueRentalRatio()) - .otherRatio(result.getOtherRatio()) - .build(); - } - -} diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptExpenseResponse.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptMonthlyExpenseResponse.java similarity index 66% rename from src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptExpenseResponse.java rename to src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptMonthlyExpenseResponse.java index dc0edc0..6dd7016 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptExpenseResponse.java +++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/in/web/dto/response/ReceiptMonthlyExpenseResponse.java @@ -1,20 +1,20 @@ package com.ClubAccount_BE.receipt.adapter.in.web.dto.response; -import com.ClubAccount_BE.receipt.domain.DetailExpenseResult; +import com.ClubAccount_BE.receipt.domain.ReceiptMonthlyExpenseResult; import java.math.BigDecimal; import java.util.UUID; import lombok.Builder; @Builder -public record ReceiptExpenseResponse( +public record ReceiptMonthlyExpenseResponse( UUID id, int year, int month, BigDecimal totalExpense ) { - public static ReceiptExpenseResponse of(DetailExpenseResult result) { - return ReceiptExpenseResponse.builder() + public static ReceiptMonthlyExpenseResponse of(ReceiptMonthlyExpenseResult result) { + return ReceiptMonthlyExpenseResponse.builder() .id(UUID.nameUUIDFromBytes((result.getYear() + "-" + result.getMonth()).getBytes())) .year(result.getYear()) .month(result.getMonth()) diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java index 2af406a..90727f5 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java +++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/ReceiptRepositoryAdapter.java @@ -59,7 +59,7 @@ public Receipt getReceipt(User user, Long receiptId) { } @Override - public List getReceiptExpenseList(User user, int year) { + public List getReceiptMonthlyExpenseList(User user, int year) { return receiptRepository .findByUserIdAndYear(user.getId(), year) .stream() diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/entity/ReceiptEntity.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/entity/ReceiptEntity.java index 22674ec..58e1b3a 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/entity/ReceiptEntity.java +++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/entity/ReceiptEntity.java @@ -72,6 +72,7 @@ public void updateReceipt(Receipt receipt) { this.amount = receipt.getAmount(); this.date = receipt.getDate(); this.etc = receipt.getEtc(); + this.amountMatched = receipt.isAmountMatched(); this.receiptItems.clear(); } diff --git a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/repository/ReceiptCustomRepositoryImpl.java b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/repository/ReceiptCustomRepositoryImpl.java index a5b1032..e7e944d 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/repository/ReceiptCustomRepositoryImpl.java +++ b/src/main/java/com/ClubAccount_BE/receipt/adapter/out/persistence/repository/ReceiptCustomRepositoryImpl.java @@ -36,7 +36,7 @@ public Page findAllByDate( List content = queryFactory .selectFrom(receiptEntity) .where(where) - .orderBy(receiptEntity.date.desc()) + .orderBy(receiptEntity.date.desc(), receiptEntity.id.desc()) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); diff --git a/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java b/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java index b2ddeaf..9bbc130 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java +++ b/src/main/java/com/ClubAccount_BE/receipt/application/port/in/FindReceiptUseCase.java @@ -1,9 +1,9 @@ package com.ClubAccount_BE.receipt.application.port.in; import com.ClubAccount_BE.core.response.PagingResponse; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryResponse; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptExpenseResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptItemResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptMonthlyExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptResponse; import java.time.LocalDate; import java.util.List; @@ -12,7 +12,7 @@ public interface FindReceiptUseCase { - ReceiptCategoryResponse getReceiptCategoryRatio(UUID link); + ReceiptCategoryExpenseResponse getReceiptCategoryExpense(UUID link); PagingResponse getReceiptList( UUID link, @@ -23,5 +23,5 @@ PagingResponse getReceiptList( List getReceiptItem(UUID link, Long receiptId); - List getReceiptExpenseList(UUID link, int year); + List getReceiptMonthlyExpenseList(UUID link, int year); } diff --git a/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java b/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java index 98ecf24..6b2a06f 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java +++ b/src/main/java/com/ClubAccount_BE/receipt/application/port/out/FindReceiptPort.java @@ -20,5 +20,5 @@ Page getReceiptList( Receipt getReceipt(User user, Long receiptId); - List getReceiptExpenseList(User user, int year); + List getReceiptMonthlyExpenseList(User user, int year); } diff --git a/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java b/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java index fd3a53f..7428c48 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java +++ b/src/main/java/com/ClubAccount_BE/receipt/application/service/FindReceiptService.java @@ -4,15 +4,15 @@ import com.ClubAccount_BE.core.exception.ApiException; import com.ClubAccount_BE.core.response.PagingResponse; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryResponse; -import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptExpenseResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptCategoryExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptItemResponse; +import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptMonthlyExpenseResponse; import com.ClubAccount_BE.receipt.adapter.in.web.dto.response.ReceiptResponse; import com.ClubAccount_BE.receipt.application.port.in.FindReceiptUseCase; import com.ClubAccount_BE.receipt.application.port.out.FindReceiptPort; -import com.ClubAccount_BE.receipt.domain.DetailCategoryResult; -import com.ClubAccount_BE.receipt.domain.DetailExpenseResult; import com.ClubAccount_BE.receipt.domain.Receipt; +import com.ClubAccount_BE.receipt.domain.ReceiptCategoryExpenseResult; +import com.ClubAccount_BE.receipt.domain.ReceiptMonthlyExpenseResult; import com.ClubAccount_BE.receipt.domain.service.ReceiptEditor; import com.ClubAccount_BE.user.application.port.out.FindUserPort; import com.ClubAccount_BE.user.domain.User; @@ -46,13 +46,17 @@ public List getReceiptItem(UUID link, Long receiptId) { } @Override - public List getReceiptExpenseList(UUID link, int year) { + public List getReceiptMonthlyExpenseList(UUID link, int year) { User user = findUserPort.getUserByLink(link); - List receiptList = findReceiptPort.getReceiptExpenseList(user, year); - List results = receiptEditor.calculateExpense(receiptList, year); + List receiptList = findReceiptPort.getReceiptMonthlyExpenseList(user, year); + List results = receiptEditor.calculateMonthlyExpense( + receiptList, + year + ); + return results.stream() - .map(ReceiptExpenseResponse::of) + .map(ReceiptMonthlyExpenseResponse::of) .toList(); } @@ -77,11 +81,11 @@ public PagingResponse getReceiptList( } @Override - public ReceiptCategoryResponse getReceiptCategoryRatio(UUID link) { + public ReceiptCategoryExpenseResponse getReceiptCategoryExpense(UUID link) { User user = findUserPort.getUserByLink(link); List receiptList = findReceiptPort.getReceiptCategoryList(user); - DetailCategoryResult result = receiptEditor.calculateCategoryRatio(receiptList); - return ReceiptCategoryResponse.of(result); + ReceiptCategoryExpenseResult result = receiptEditor.calculateCategoryExpense(receiptList); + return ReceiptCategoryExpenseResponse.of(result); } } diff --git a/src/main/java/com/ClubAccount_BE/receipt/domain/DetailCategoryResult.java b/src/main/java/com/ClubAccount_BE/receipt/domain/DetailCategoryResult.java deleted file mode 100644 index 8ecadc7..0000000 --- a/src/main/java/com/ClubAccount_BE/receipt/domain/DetailCategoryResult.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.ClubAccount_BE.receipt.domain; - -import lombok.Builder; -import lombok.Getter; - -@Getter -public class DetailCategoryResult { - - private final float groupDiningRatio; - private final float supplyPurchaseRatio; - private final float subscriptionRatio; - private final float venueRentalRatio; - private final float otherRatio; - - @Builder - private DetailCategoryResult( - float groupDiningRatio, - float supplyPurchaseRatio, - float subscriptionRatio, - float venueRentalRatio, - float otherRatio - ) { - this.groupDiningRatio = groupDiningRatio; - this.supplyPurchaseRatio = supplyPurchaseRatio; - this.subscriptionRatio = subscriptionRatio; - this.venueRentalRatio = venueRentalRatio; - this.otherRatio = otherRatio; - } - - public static DetailCategoryResult of( - float groupDiningRatio, - float supplyPurchaseRatio, - float subscriptionRatio, - float venueRentalRatio, - float otherRatio - ) { - return DetailCategoryResult.builder() - .groupDiningRatio(groupDiningRatio) - .supplyPurchaseRatio(supplyPurchaseRatio) - .subscriptionRatio(subscriptionRatio) - .venueRentalRatio(venueRentalRatio) - .otherRatio(otherRatio) - .build(); - } -} diff --git a/src/main/java/com/ClubAccount_BE/receipt/domain/ReceiptCategoryExpenseResult.java b/src/main/java/com/ClubAccount_BE/receipt/domain/ReceiptCategoryExpenseResult.java new file mode 100644 index 0000000..4f6a9b3 --- /dev/null +++ b/src/main/java/com/ClubAccount_BE/receipt/domain/ReceiptCategoryExpenseResult.java @@ -0,0 +1,46 @@ +package com.ClubAccount_BE.receipt.domain; + +import java.math.BigDecimal; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class ReceiptCategoryExpenseResult { + + private final BigDecimal groupDiningExpense; + private final BigDecimal supplyPurchaseExpense; + private final BigDecimal subscriptionExpense; + private final BigDecimal venueRentalExpense; + private final BigDecimal otherExpense; + + @Builder + private ReceiptCategoryExpenseResult( + BigDecimal groupDiningExpense, + BigDecimal supplyPurchaseExpense, + BigDecimal subscriptionExpense, + BigDecimal venueRentalExpense, + BigDecimal otherExpense + ) { + this.groupDiningExpense = groupDiningExpense; + this.supplyPurchaseExpense = supplyPurchaseExpense; + this.subscriptionExpense = subscriptionExpense; + this.venueRentalExpense = venueRentalExpense; + this.otherExpense = otherExpense; + } + + public static ReceiptCategoryExpenseResult of( + BigDecimal groupDiningExpense, + BigDecimal supplyPurchaseExpense, + BigDecimal subscriptionExpense, + BigDecimal venueRentalExpense, + BigDecimal otherExpense + ) { + return ReceiptCategoryExpenseResult.builder() + .groupDiningExpense(groupDiningExpense) + .supplyPurchaseExpense(supplyPurchaseExpense) + .subscriptionExpense(subscriptionExpense) + .venueRentalExpense(venueRentalExpense) + .otherExpense(otherExpense) + .build(); + } +} diff --git a/src/main/java/com/ClubAccount_BE/receipt/domain/DetailExpenseResult.java b/src/main/java/com/ClubAccount_BE/receipt/domain/ReceiptMonthlyExpenseResult.java similarity index 63% rename from src/main/java/com/ClubAccount_BE/receipt/domain/DetailExpenseResult.java rename to src/main/java/com/ClubAccount_BE/receipt/domain/ReceiptMonthlyExpenseResult.java index 33c99a0..a49bc41 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/domain/DetailExpenseResult.java +++ b/src/main/java/com/ClubAccount_BE/receipt/domain/ReceiptMonthlyExpenseResult.java @@ -5,21 +5,21 @@ import lombok.Getter; @Getter -public class DetailExpenseResult { +public class ReceiptMonthlyExpenseResult { private final int year; private final int month; private final BigDecimal totalExpense; @Builder - private DetailExpenseResult(int year, int month, BigDecimal totalExpense) { + private ReceiptMonthlyExpenseResult(int year, int month, BigDecimal totalExpense) { this.year = year; this.month = month; this.totalExpense = totalExpense; } - public static DetailExpenseResult of(int year, int month, BigDecimal totalExpense) { - return DetailExpenseResult.builder() + public static ReceiptMonthlyExpenseResult of(int year, int month, BigDecimal totalExpense) { + return ReceiptMonthlyExpenseResult.builder() .year(year) .month(month) .totalExpense(totalExpense) diff --git a/src/main/java/com/ClubAccount_BE/receipt/domain/service/ReceiptEditor.java b/src/main/java/com/ClubAccount_BE/receipt/domain/service/ReceiptEditor.java index 6d80bd1..8972398 100644 --- a/src/main/java/com/ClubAccount_BE/receipt/domain/service/ReceiptEditor.java +++ b/src/main/java/com/ClubAccount_BE/receipt/domain/service/ReceiptEditor.java @@ -1,9 +1,15 @@ package com.ClubAccount_BE.receipt.domain.service; -import com.ClubAccount_BE.receipt.domain.DetailCategoryResult; -import com.ClubAccount_BE.receipt.domain.DetailExpenseResult; +import static com.ClubAccount_BE.receipt.domain.type.ReceiptCategory.GROUP_DINING; +import static com.ClubAccount_BE.receipt.domain.type.ReceiptCategory.OTHER; +import static com.ClubAccount_BE.receipt.domain.type.ReceiptCategory.SUBSCRIPTION; +import static com.ClubAccount_BE.receipt.domain.type.ReceiptCategory.SUPPLY_PURCHASE; +import static com.ClubAccount_BE.receipt.domain.type.ReceiptCategory.VENUE_RENTAL; + import com.ClubAccount_BE.receipt.domain.Receipt; +import com.ClubAccount_BE.receipt.domain.ReceiptCategoryExpenseResult; import com.ClubAccount_BE.receipt.domain.ReceiptItem; +import com.ClubAccount_BE.receipt.domain.ReceiptMonthlyExpenseResult; import com.ClubAccount_BE.receipt.domain.type.ReceiptCategory; import java.math.BigDecimal; import java.util.List; @@ -27,31 +33,32 @@ public boolean checkAmountMatch(Receipt receipt, List items) { } /** - * 영수증 카테고리 비율 계산 + * 영수증 카테고리별 지출 계산 */ - public DetailCategoryResult calculateCategoryRatio(List receipts) { - int total = receipts.size(); - - if (total == 0) { - return DetailCategoryResult.of(0f, 0f, 0f, 0f, 0f); - } + public ReceiptCategoryExpenseResult calculateCategoryExpense(List receipts) { - Map counts = receipts.stream() - .collect(Collectors.groupingBy(Receipt::getCategory, Collectors.counting())); + Map categoryExpense = receipts.stream() + .collect(Collectors.groupingBy( + Receipt::getCategory, + Collectors.reducing(BigDecimal.ZERO, Receipt::getAmount, BigDecimal::add) + )); - return DetailCategoryResult.of( - ratio(counts.get(ReceiptCategory.GROUP_DINING), total), - ratio(counts.get(ReceiptCategory.SUPPLY_PURCHASE), total), - ratio(counts.get(ReceiptCategory.SUBSCRIPTION), total), - ratio(counts.get(ReceiptCategory.VENUE_RENTAL), total), - ratio(counts.get(ReceiptCategory.OTHER), total) + return ReceiptCategoryExpenseResult.of( + categoryExpense.getOrDefault(GROUP_DINING, BigDecimal.ZERO), + categoryExpense.getOrDefault(SUPPLY_PURCHASE, BigDecimal.ZERO), + categoryExpense.getOrDefault(SUBSCRIPTION, BigDecimal.ZERO), + categoryExpense.getOrDefault(VENUE_RENTAL, BigDecimal.ZERO), + categoryExpense.getOrDefault(OTHER, BigDecimal.ZERO) ); } /** * 영수증 월별 지출 계산 */ - public List calculateExpense(List receiptList, int year) { + public List calculateMonthlyExpense( + List receiptList, + int year + ) { Map monthlyExpense = receiptList.stream() .collect(Collectors.groupingBy( receipt -> receipt.getDate().getMonthValue(), @@ -59,14 +66,10 @@ public List calculateExpense(List receiptList, int )); return IntStream.rangeClosed(1, 12) - .mapToObj(month -> DetailExpenseResult.of( + .mapToObj(month -> ReceiptMonthlyExpenseResult.of( year, month, monthlyExpense.getOrDefault(month, BigDecimal.ZERO))) .collect(Collectors.toList()); } - - private float ratio(Long count, int total) { - return count == null ? 0f : (count * 100f / total); - } }