diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/category/controller/CategoryController.java b/src/main/java/com/bbteam/budgetbuddies/domain/category/controller/CategoryController.java index 1732ac7f..f3dedb20 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/category/controller/CategoryController.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/category/controller/CategoryController.java @@ -1,34 +1,41 @@ package com.bbteam.budgetbuddies.domain.category.controller; +import java.util.List; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + import com.bbteam.budgetbuddies.domain.category.dto.CategoryRequestDTO; import com.bbteam.budgetbuddies.domain.category.dto.CategoryResponseDTO; import com.bbteam.budgetbuddies.domain.category.service.CategoryService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import java.util.List; +import lombok.RequiredArgsConstructor; @RestController @RequiredArgsConstructor @RequestMapping("/categories") public class CategoryController implements CategoryApi { - private final CategoryService categoryService; - - @Override - @PostMapping("/add/{userId}") - public ResponseEntity createCategory( - @PathVariable Long userId, - @RequestBody CategoryRequestDTO categoryRequestDTO) { - CategoryResponseDTO response = categoryService.createCategory(userId, categoryRequestDTO); - return ResponseEntity.ok(response); - } - - @Override - @GetMapping("/get/{userId}") - public ResponseEntity> getUserCategories(@PathVariable Long userId) { - List response = categoryService.getUserCategories(userId); - return ResponseEntity.ok(response); - } + private final CategoryService categoryService; + + @Override + @PostMapping("/add/{userId}") + public ResponseEntity createCategory( + @PathVariable Long userId, + @RequestBody CategoryRequestDTO categoryRequestDTO) { + CategoryResponseDTO response = categoryService.createCategory(userId, categoryRequestDTO); + return ResponseEntity.ok(response); + } + + @Override + @GetMapping("/get/{userId}") + public ResponseEntity> getUserCategories(@PathVariable Long userId) { + List response = categoryService.getUserCategories(userId); + return ResponseEntity.ok(response); + } } diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalApi.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalApi.java index 25249f26..c14c7262 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalApi.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalApi.java @@ -2,8 +2,8 @@ import java.time.LocalDate; -import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalListRequestDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; @@ -18,27 +18,19 @@ public interface ConsumptionGoalApi { @Operation(summary = "또래들이 가장 큰 계획을 세운 카테고리 조회 Top4 API", description = "특정 사용자의 소비 목표 카테고리별 소비 목표 금액을 조회하는 API 입니다.") @ApiResponses(value = {@ApiResponse(responseCode = "COMMON200", description = "OK, 성공")}) - @Parameters({@Parameter(name = "top", description = "가장 큰 목표를 세운 카테고리의 개수를 지정합니다."), - @Parameter(name = "userId", description = "로그인 한 유저 아이디"), + @Parameters({@Parameter(name = "userId", description = "로그인 한 유저 아이디"), @Parameter(name = "peerAgeStart", description = "또래나이 시작 범위"), @Parameter(name = "peerAgeEnd", description = "또래나이 끝 범위"), @Parameter(name = "peerGender", description = "또래 성별")}) - ResponseEntity getTopGoalCategoriesList(int top, Long userId, - int peerAgeStart, int peerAgeEnd, String peerGender); + ResponseEntity getTopConsumptionGoalCategories(Long userId, int peerAgeStart, int peerAgeEnd, String peerGender); - @Operation(summary = "또래들이 가장 큰 계획을 세운 카테고리 조회 API", description = "특정 사용자의 소비 목표 카테고리별 소비 목표 금액을 전체 조회하는 API 입니다.") + @Operation(summary = "또래들이 가장 많이 계획한 카테고리와 평균 금액 및 내 목표금액 차이 조회 API", description = "특정 사용자의 또래 소비 카테고리별 평균 목표 금액을 조회하는 API 입니다.") @ApiResponses(value = {@ApiResponse(responseCode = "COMMON200", description = "OK, 성공")}) @Parameters({@Parameter(name = "userId", description = "로그인 한 유저 아이디"), @Parameter(name = "peerAgeStart", description = "또래나이 시작 범위"), @Parameter(name = "peerAgeEnd", description = "또래나이 끝 범위"), @Parameter(name = "peerGender", description = "또래 성별")}) - ResponseEntity getTopGoalCategoriesPage(Long userId, - int peerAgeStart, int peerAgeEnd, String peerGender, Pageable pageable); - - @Operation(summary = "또래가 가장 큰 계획을 세운 카테고리와 이번 주 사용한 금액 조회 API", description = "로그인 한 유저의 또래 중 가장 큰 소비 목표 금액을 가진 카테고리와 이번 주 사용한 금액을 조회하는 API 입니다") - @ApiResponses(value = {@ApiResponse(responseCode = "COMMON200", description = "OK, 성공")}) - @Parameters({@Parameter(name = "userId", description = "로그인 한 유저 아이디")}) - ResponseEntity getTopGoalCategory(Long userId); + ResponseEntity getAllConsumptionGoalCategories(Long userId, int peerAgeStart, int peerAgeEnd, String peerGender); @Operation(summary = "또래나이와 성별 조회 API", description = "또래나이와 성별을 조회하는 API 입니다.") @ApiResponses(value = {@ApiResponse(responseCode = "COMMON200", description = "OK, 성공")}) @@ -56,22 +48,23 @@ ResponseEntity getTopGoalCategoriesPage(Long userId, ResponseEntity updateOrElseGenerateConsumptionGoal(Long userId, ConsumptionGoalListRequestDto consumptionGoalListRequestDto); - @Operation(summary = "또래들이 가장 많이한 소비 카테고리 조회 Top4 API", description = "특정 사용자의 소비 카테고리별 소비 금액을 조회하는 API 입니다.") + @Operation(summary = "또래들이 가장 많이한 소비 카테고리 조회 Top3 API", description = "특정 사용자의 또래 소비 카테고리별 소비 건 수을 조회하는 API 입니다.") @ApiResponses(value = {@ApiResponse(responseCode = "COMMON200", description = "OK, 성공")}) - @Parameters({@Parameter(name = "top", description = "가장 큰 소비 카테고리의 개수를 지정합니다."), - @Parameter(name = "userId", description = "로그인 한 유저 아이디"), + @Parameters({@Parameter(name = "userId", description = "로그인 한 유저 아이디"), @Parameter(name = "peerAgeStart", description = "또래나이 시작 범위"), @Parameter(name = "peerAgeEnd", description = "또래나이 끝 범위"), @Parameter(name = "peerGender", description = "또래 성별")}) - ResponseEntity getConsumptionGoalList(int top, Long userId, int peerAgeStart, int peerAgeEnd, - String peerGender); + ResponseEntity getTopConsumptionCategories(Long userId, int peerAgeStart, int peerAgeEnd, String peerGender); - @Operation(summary = "또래들이 가장 많이한 소비 카테고리 조회 API", description = "특정 사용자의 소비 카테고리별 소비 금액을 전체 조회하는 API 입니다.") + @Operation(summary = "또래들이 가장 많이한 소비 카테고리와 평균 금액 및 내 소비금액 차이 조회 API", description = "특정 사용자의 또래 소비 카테고리별 평균 소비 금액을 조회하는 API 입니다.") @ApiResponses(value = {@ApiResponse(responseCode = "COMMON200", description = "OK, 성공")}) @Parameters({@Parameter(name = "userId", description = "로그인 한 유저 아이디"), @Parameter(name = "peerAgeStart", description = "또래나이 시작 범위"), @Parameter(name = "peerAgeEnd", description = "또래나이 끝 범위"), @Parameter(name = "peerGender", description = "또래 성별")}) - ResponseEntity getConsumptionGoalPage(Long userId, int peerAgeStart, int peerAgeEnd, String peerGender, - Pageable pageable); + ResponseEntity getAllConsumptionCategories(Long userId, int peerAgeStart, int peerAgeEnd, String peerGender); + + @Operation(summary = "또래들이 가장 큰 목표로 세운 카테고리와 그 카테고리에서 이번주 사용한 금액 조회 API", description = "특정 사용자의 또래 소비 카테고리별 이번주 소비 금액을 조회하는 API 입니다.") + @ApiResponses(value = {@ApiResponse(responseCode = "COMMON200", description = "OK, 성공")}) + ResponseEntity getTopCategoryAndConsumptionAmount(@PathVariable Long userId); } \ No newline at end of file diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalController.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalController.java index c435c94e..04add868 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalController.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/controller/ConsumptionGoalController.java @@ -3,8 +3,6 @@ import java.time.LocalDate; import java.util.List; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -15,12 +13,12 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AllConsumptionCategoryResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalListRequestDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopConsumptionResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopCategoryConsumptionDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.service.ConsumptionGoalService; import lombok.RequiredArgsConstructor; @@ -33,32 +31,24 @@ public class ConsumptionGoalController implements ConsumptionGoalApi { private final ConsumptionGoalService consumptionGoalService; @Override - @GetMapping("/top-categories/top-goal/{top}") - public ResponseEntity getTopGoalCategoriesList(@PathVariable(name = "top") int top, - @RequestParam(name = "userId") Long userId, + @GetMapping("/top-categories/top-goal/4") + public ResponseEntity getTopConsumptionGoalCategories(@RequestParam(name = "userId") Long userId, @RequestParam(name = "peerAgeStart", defaultValue = "0") int peerAgeStart, @RequestParam(name = "peerAgeEnd", defaultValue = "0") int peerAgeEnd, @RequestParam(name = "peerGender", defaultValue = "none") String peerGender) { - List topCategoriesList = consumptionGoalService.getTopGoalCategoriesLimit(top, - userId, - peerAgeStart, peerAgeEnd, peerGender); + List topCategoriesList = consumptionGoalService.getTopConsumptionGoalCategories( + userId, peerAgeStart, peerAgeEnd, peerGender); return ResponseEntity.ok(topCategoriesList); } @GetMapping("/top-categories/top-goal") - public ResponseEntity getTopGoalCategoriesPage(@RequestParam(name = "userId") Long userId, + public ResponseEntity getAllConsumptionGoalCategories(@RequestParam(name = "userId") Long userId, @RequestParam(name = "peerAgeStart", defaultValue = "0") int peerAgeStart, @RequestParam(name = "peerAgeEnd", defaultValue = "0") int peerAgeEnd, - @RequestParam(name = "peerGender", defaultValue = "none") String peerGender, Pageable pageable) { - Page topCategoriesPage = consumptionGoalService.getTopGoalCategories(userId, - peerAgeStart, peerAgeEnd, peerGender, pageable); - return ResponseEntity.ok(topCategoriesPage.getContent()); - } - - @Override - @GetMapping("/top-category/top-goal") - public ResponseEntity getTopGoalCategory(@RequestParam(name = "userId") Long userId) { - ConsumptionAnalysisResponseDTO response = consumptionGoalService.getTopCategoryAndConsumptionAmount(userId); + @RequestParam(name = "peerGender", defaultValue = "none") String peerGender) { + List response = consumptionGoalService.getAllConsumptionGoalCategories( + userId, + peerAgeStart, peerAgeEnd, peerGender); return ResponseEntity.ok(response); } @@ -68,7 +58,7 @@ public ResponseEntity getPeerInfo(@RequestParam(name = "userId") Long userId, @RequestParam(name = "peerAgeStart", defaultValue = "0") int peerAgeStart, @RequestParam(name = "peerAgeEnd", defaultValue = "0") int peerAgeEnd, @RequestParam(name = "peerGender", defaultValue = "none") String peerGender) { - PeerInfoResponseDTO response = consumptionGoalService.getPeerInfo(userId, peerAgeStart, peerAgeEnd, peerGender); + PeerInfoResponseDto response = consumptionGoalService.getPeerInfo(userId, peerAgeStart, peerAgeEnd, peerGender); return ResponseEntity.ok(response); } @@ -90,24 +80,29 @@ public ResponseEntity updateOrElseGenerateConsum .body(consumptionGoalService.updateConsumptionGoals(userId, consumptionGoalListRequestDto)); } - @GetMapping("/top-categories/top-consumption/{top}") - public ResponseEntity getConsumptionGoalList(@PathVariable(name = "top") int top, - @RequestParam(name = "userId") Long userId, + @GetMapping("/top-categories/top-consumption/3") + public ResponseEntity getTopConsumptionCategories(@RequestParam(name = "userId") Long userId, @RequestParam(name = "peerAgeStart", defaultValue = "0") int peerAgeStart, @RequestParam(name = "peerAgeEnd", defaultValue = "0") int peerAgeEnd, @RequestParam(name = "peerGender", defaultValue = "none") String peerGender) { - List response = consumptionGoalService.getTopConsumptionsLimit(top, userId, + List topCategoriesList = consumptionGoalService.getTopConsumptionCategories(userId, peerAgeStart, peerAgeEnd, peerGender); - return ResponseEntity.ok(response); + return ResponseEntity.ok(topCategoriesList); } @GetMapping("/top-categories/top-consumption") - public ResponseEntity getConsumptionGoalPage(@RequestParam(name = "userId") Long userId, + public ResponseEntity getAllConsumptionCategories(@RequestParam(name = "userId") Long userId, @RequestParam(name = "peerAgeStart", defaultValue = "0") int peerAgeStart, @RequestParam(name = "peerAgeEnd", defaultValue = "0") int peerAgeEnd, - @RequestParam(name = "peerGender", defaultValue = "none") String peerGender, Pageable pageable) { - Page response = consumptionGoalService.getTopConsumptions(userId, - peerAgeStart, peerAgeEnd, peerGender, pageable); - return ResponseEntity.ok(response.getContent()); + @RequestParam(name = "peerGender", defaultValue = "none") String peerGender) { + List response = consumptionGoalService.getAllConsumptionCategories(userId, + peerAgeStart, peerAgeEnd, peerGender); + return ResponseEntity.ok(response); + } + + @GetMapping("/top-categories/top-consumption/{userId}") + public ResponseEntity getTopCategoryAndConsumptionAmount(@PathVariable Long userId) { + return ResponseEntity.ok(consumptionGoalService.getTopCategoryAndConsumptionAmount(userId)); } + } \ No newline at end of file diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/ConsumptionAnalysisConverter.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/ConsumptionAnalysisConverter.java deleted file mode 100644 index 27b34819..00000000 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/ConsumptionAnalysisConverter.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.bbteam.budgetbuddies.domain.consumptiongoal.converter; - -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; - -public class ConsumptionAnalysisConverter { - - public static ConsumptionAnalysisResponseDTO fromEntity(ConsumptionGoal consumptionGoal, Long topAmount) { - - return ConsumptionAnalysisResponseDTO.builder() - .goalCategory(consumptionGoal.getCategory().getName()) - .currentWeekConsumptionAmount(topAmount) - .build(); - } -} diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/ConsumptionGoalConverter.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/ConsumptionGoalConverter.java index 2def3e93..26ef9c81 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/ConsumptionGoalConverter.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/ConsumptionGoalConverter.java @@ -3,13 +3,16 @@ import java.time.LocalDate; import java.util.List; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.UserConsumptionGoalResponse; import org.springframework.stereotype.Component; import com.bbteam.budgetbuddies.domain.category.entity.Category; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.UserConsumptionGoalResponse; import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; +import com.bbteam.budgetbuddies.enums.Gender; @Component public class ConsumptionGoalConverter { @@ -52,10 +55,28 @@ private Long sumTotalGoalAmount(List consumptionGoal public UserConsumptionGoalResponse toUserConsumptionGoalResponse(ConsumptionGoal consumptionGoal) { return UserConsumptionGoalResponse.builder() - .categoryId(consumptionGoal.getCategory().getId()) - .goalMonth(consumptionGoal.getGoalMonth()) - .consumeAmount(consumptionGoal.getConsumeAmount()) - .goalAmount(consumptionGoal.getGoalAmount()) - .build(); + .categoryId(consumptionGoal.getCategory().getId()) + .goalMonth(consumptionGoal.getGoalMonth()) + .consumeAmount(consumptionGoal.getConsumeAmount()) + .goalAmount(consumptionGoal.getGoalAmount()) + .build(); + } + + public ConsumptionAnalysisResponseDto toTopCategoryAndConsumptionAmount(String categoryName, + Long topAmount) { + + return ConsumptionAnalysisResponseDto.builder() + .goalCategory(categoryName) + .currentWeekConsumptionAmount(topAmount) + .build(); + } + + public PeerInfoResponseDto toPeerInfo(int peerAgeStart, int peerAgeEnd, Gender peerGender) { + + return PeerInfoResponseDto.builder() + .peerAgeStart(peerAgeStart) + .peerAgeEnd(peerAgeEnd) + .peerGender(peerGender.name()) + .build(); } } diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/PeerInfoConverter.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/PeerInfoConverter.java deleted file mode 100644 index d6c3eb24..00000000 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/PeerInfoConverter.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.bbteam.budgetbuddies.domain.consumptiongoal.converter; - -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDTO; -import com.bbteam.budgetbuddies.enums.Gender; - -public class PeerInfoConverter { - - public static PeerInfoResponseDTO fromEntity(int peerAgeStart, int peerAgeEnd, Gender peerGender) { - - return PeerInfoResponseDTO.builder() - .peerAgeStart(peerAgeStart) - .peerAgeEnd(peerAgeEnd) - .peerGender(peerGender.name()) - .build(); - } -} diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/TopCategoryConverter.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/TopCategoryConverter.java deleted file mode 100644 index 239dc8da..00000000 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/TopCategoryConverter.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.bbteam.budgetbuddies.domain.consumptiongoal.converter; - -import org.springframework.stereotype.Component; - -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; - -@Component -public class TopCategoryConverter { - - public static TopGoalCategoryResponseDTO fromEntity(ConsumptionGoal consumptionGoal) { - if (consumptionGoal == null || consumptionGoal.getCategory() == null) { - return null; - } - - return TopGoalCategoryResponseDTO.builder() - .categoryName(consumptionGoal.getCategory().getName()) - .goalAmount(consumptionGoal.getGoalAmount()) - .build(); - } -} diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/TopConsumptionConverter.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/TopConsumptionConverter.java deleted file mode 100644 index 9f37e9c1..00000000 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/converter/TopConsumptionConverter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.bbteam.budgetbuddies.domain.consumptiongoal.converter; - -import org.springframework.stereotype.Component; - -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopConsumptionResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; - -@Component -public class TopConsumptionConverter { - public static TopConsumptionResponseDTO fromEntity(ConsumptionGoal consumptionGoal) { - - return TopConsumptionResponseDTO.builder() - .categoryName(consumptionGoal.getCategory().getName()) - .consumeAmount(consumptionGoal.getConsumeAmount()) - .build(); - } -} diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/AllConsumptionCategoryResponseDto.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/AllConsumptionCategoryResponseDto.java new file mode 100644 index 00000000..0ed7b0df --- /dev/null +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/AllConsumptionCategoryResponseDto.java @@ -0,0 +1,19 @@ +package com.bbteam.budgetbuddies.domain.consumptiongoal.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AllConsumptionCategoryResponseDto { + + private String categoryName; + + private Long avgAmount; + + private Long amountDifference; +} diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/AvgConsumptionGoalDto.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/AvgConsumptionGoalDto.java new file mode 100644 index 00000000..e73a8c51 --- /dev/null +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/AvgConsumptionGoalDto.java @@ -0,0 +1,19 @@ +package com.bbteam.budgetbuddies.domain.consumptiongoal.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class AvgConsumptionGoalDto { + + private Long categoryId; + private Long averageAmount; + + public AvgConsumptionGoalDto(Long categoryId, Double averageAmount) { + this.categoryId = categoryId; + this.averageAmount = (averageAmount != null) ? averageAmount.longValue() : 0L; + } +} \ No newline at end of file diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/CategoryConsumptionCountDto.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/CategoryConsumptionCountDto.java new file mode 100644 index 00000000..05068c32 --- /dev/null +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/CategoryConsumptionCountDto.java @@ -0,0 +1,13 @@ +package com.bbteam.budgetbuddies.domain.consumptiongoal.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class CategoryConsumptionCountDto { + private Long categoryId; + private Long consumptionCount; +} diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/ConsumptionAnalysisResponseDTO.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/ConsumptionAnalysisResponseDto.java similarity index 87% rename from src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/ConsumptionAnalysisResponseDTO.java rename to src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/ConsumptionAnalysisResponseDto.java index 10c505be..127cdd58 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/ConsumptionAnalysisResponseDTO.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/ConsumptionAnalysisResponseDto.java @@ -9,7 +9,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -public class ConsumptionAnalysisResponseDTO { +public class ConsumptionAnalysisResponseDto { private String goalCategory; diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/MyConsumptionGoalDto.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/MyConsumptionGoalDto.java new file mode 100644 index 00000000..b9217b90 --- /dev/null +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/MyConsumptionGoalDto.java @@ -0,0 +1,14 @@ +package com.bbteam.budgetbuddies.domain.consumptiongoal.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class MyConsumptionGoalDto { + + private Long categoryId; + private Long MyAmount; +} \ No newline at end of file diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/PeerInfoResponseDTO.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/PeerInfoResponseDto.java similarity index 90% rename from src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/PeerInfoResponseDTO.java rename to src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/PeerInfoResponseDto.java index 3ac0d041..a20e0172 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/PeerInfoResponseDTO.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/PeerInfoResponseDto.java @@ -9,7 +9,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -public class PeerInfoResponseDTO { +public class PeerInfoResponseDto { private int peerAgeStart; diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopConsumptionResponseDTO.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopCategoryConsumptionDto.java similarity index 78% rename from src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopConsumptionResponseDTO.java rename to src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopCategoryConsumptionDto.java index e6041e2b..d50c88e6 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopConsumptionResponseDTO.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopCategoryConsumptionDto.java @@ -9,9 +9,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -public class TopConsumptionResponseDTO { - +public class TopCategoryConsumptionDto { private String categoryName; - - private Long consumeAmount; + private Long consumptionCount; } diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopGoalCategoryResponseDTO.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopGoalCategoryResponseDto.java similarity index 87% rename from src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopGoalCategoryResponseDTO.java rename to src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopGoalCategoryResponseDto.java index 99c394b4..ba8549a1 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopGoalCategoryResponseDTO.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/dto/TopGoalCategoryResponseDto.java @@ -9,7 +9,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -public class TopGoalCategoryResponseDTO { +public class TopGoalCategoryResponseDto { private String categoryName; diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepository.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepository.java index 0550465e..00986dd8 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepository.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepository.java @@ -4,14 +4,15 @@ import java.util.List; import java.util.Optional; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import com.bbteam.budgetbuddies.domain.category.entity.Category; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AvgConsumptionGoalDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.CategoryConsumptionCountDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.MyConsumptionGoalDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; import com.bbteam.budgetbuddies.domain.user.entity.User; import com.bbteam.budgetbuddies.enums.Gender; @@ -19,43 +20,64 @@ @Repository public interface ConsumptionGoalRepository extends JpaRepository { - @Query("SELECT cg FROM ConsumptionGoal cg " + "WHERE cg.category.isDefault = true " - + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender " - + "AND cg.goalMonth >= :currentMonth " + "ORDER BY cg.goalAmount DESC limit :top") - List findTopCategoriesAndGoalAmountLimit(@Param("top") int top, - @Param("peerAgeStart") int peerAgeStart, @Param("peerAgeEnd") int peerAgeEnd, - @Param("peerGender") Gender peerGender, @Param("currentMonth") LocalDate currentMonth); - - @Query("SELECT cg FROM ConsumptionGoal cg " + "WHERE cg.category.isDefault = true " - + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender " - + "AND cg.goalMonth >= :currentMonth " + "ORDER BY cg.goalAmount DESC") - Page findTopCategoriesAndGoalAmount(@Param("peerAgeStart") int peerAgeStart, - @Param("peerAgeEnd") int peerAgeEnd, @Param("peerGender") Gender peerGender, - @Param("currentMonth") LocalDate currentMonth, Pageable pageable); - @Query(value = "SELECT cg FROM ConsumptionGoal AS cg WHERE cg.user.id = :userId AND cg.goalMonth = :goalMonth") List findConsumptionGoalByUserIdAndGoalMonth(Long userId, LocalDate goalMonth); Optional findConsumptionGoalByUserAndCategoryAndGoalMonth(User user, Category category, LocalDate goalMonth); - @Query("SELECT cg FROM ConsumptionGoal cg JOIN cg.category c WHERE c.id = :categoryId AND cg.goalMonth " - + "BETWEEN :startOfWeek AND :endOfWeek ORDER BY cg.consumeAmount DESC limit 1") - Optional findTopConsumptionByCategoryIdAndCurrentWeek(@Param("categoryId") Long categoryId, - @Param("startOfWeek") LocalDate startOfWeek, @Param("endOfWeek") LocalDate endOfWeek); - - @Query("SELECT cg FROM ConsumptionGoal cg " + "WHERE cg.category.isDefault = true " - + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender " - + "AND cg.goalMonth >= :currentMonth " + "ORDER BY cg.consumeAmount DESC limit :top") - List findTopConsumptionAndConsumeAmountLimit(@Param("top") int top, - @Param("peerAgeStart") int peerAgeStart, @Param("peerAgeEnd") int peerAgeEnd, - @Param("peerGender") Gender peerGender, @Param("currentMonth") LocalDate currentMonth); - - @Query("SELECT cg FROM ConsumptionGoal cg " + "WHERE cg.category.isDefault = true " - + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender " - + "AND cg.goalMonth >= :currentMonth " + "ORDER BY cg.consumeAmount DESC") - Page findTopConsumptionAndConsumeAmount(@Param("peerAgeStart") int peerAgeStart, - @Param("peerAgeEnd") int peerAgeEnd, @Param("peerGender") Gender peerGender, - @Param("currentMonth") LocalDate currentMonth, Pageable pageable); - -} \ No newline at end of file + @Query("SELECT AVG(cg.consumeAmount) FROM ConsumptionGoal cg " + "JOIN cg.category c " + "WHERE c.id = :categoryId " + + "AND cg.goalMonth BETWEEN :startOfWeek AND :endOfWeek " + + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender") + Optional findAvgConsumptionByCategoryIdAndCurrentWeek( + @Param("categoryId") Long categoryId, @Param("startOfWeek") LocalDate startOfWeek, + @Param("endOfWeek") LocalDate endOfWeek, @Param("peerAgeStart") int peerAgeStart, + @Param("peerAgeEnd") int peerAgeEnd, @Param("peerGender") Gender peerGender); + + @Query( + "SELECT new com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AvgConsumptionGoalDto(" + + "cg.category.id, AVG(cg.consumeAmount))" + + "FROM ConsumptionGoal cg " + "WHERE cg.category.isDefault = true " + + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender " + + "AND cg.goalMonth >= :currentMonth " + "GROUP BY cg.category.id " + "ORDER BY AVG(cg.consumeAmount) DESC") + List findAvgConsumptionAmountByCategory( + @Param("peerAgeStart") int peerAgeStart, + @Param("peerAgeEnd") int peerAgeEnd, + @Param("peerGender") Gender peerGender, + @Param("currentMonth") LocalDate currentMonth); + + @Query("SELECT new com.bbteam.budgetbuddies.domain.consumptiongoal.dto.MyConsumptionGoalDto(" + + "cg.category.id, SUM(cg.consumeAmount)) " + "FROM ConsumptionGoal cg " + + "WHERE cg.category.isDefault = true " + "AND cg.user.id = :userId " + + "GROUP BY cg.category.id " + "ORDER BY cg.category.id") + List findAllConsumptionAmountByUserId(@Param("userId") Long userId); + + @Query( + "SELECT new com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AvgConsumptionGoalDto(cg.category.id, AVG(" + + "cg.goalAmount))" + + "FROM ConsumptionGoal cg " + "WHERE cg.category.isDefault = true " + + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender " + + "AND cg.goalMonth >= :currentMonth " + "GROUP BY cg.category.id " + "ORDER BY AVG(cg.goalAmount) DESC") + List findAvgGoalAmountByCategory( + @Param("peerAgeStart") int peerAgeStart, + @Param("peerAgeEnd") int peerAgeEnd, + @Param("peerGender") Gender peerGender, + @Param("currentMonth") LocalDate currentMonth); + + @Query("SELECT new com.bbteam.budgetbuddies.domain.consumptiongoal.dto.MyConsumptionGoalDto(" + + "cg.category.id, SUM(cg.goalAmount)) " + "FROM ConsumptionGoal cg " + + "WHERE cg.category.isDefault = true " + "AND cg.user.id = :userId " + + "GROUP BY cg.category.id " + "ORDER BY cg.category.id") + List findAllGoalAmountByUserId(@Param("userId") Long userId); + + @Query( + "SELECT new com.bbteam.budgetbuddies.domain.consumptiongoal.dto.CategoryConsumptionCountDto(" + + "cg.category.id, COUNT(cg)) " + "FROM ConsumptionGoal cg " + "WHERE cg.category.isDefault = true " + + "AND cg.user.age BETWEEN :peerAgeStart AND :peerAgeEnd " + "AND cg.user.gender = :peerGender " + + "AND cg.goalMonth >= :currentMonth " + "GROUP BY cg.category.id " + "ORDER BY COUNT(cg) DESC") + List findTopCategoriesByConsumptionCount( + @Param("peerAgeStart") int peerAgeStart, + @Param("peerAgeEnd") int peerAgeEnd, + @Param("peerGender") Gender peerGender, + @Param("currentMonth") LocalDate currentMonth); +} diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalService.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalService.java index 041ce876..27553813 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalService.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalService.java @@ -3,16 +3,15 @@ import java.time.LocalDate; import java.util.List; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AllConsumptionCategoryResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalListRequestDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopConsumptionResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopCategoryConsumptionDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDto; import com.bbteam.budgetbuddies.domain.expense.dto.ExpenseUpdateRequestDto; import com.bbteam.budgetbuddies.domain.expense.entity.Expense; import com.bbteam.budgetbuddies.domain.user.entity.User; @@ -20,20 +19,20 @@ @Service public interface ConsumptionGoalService { - List getTopGoalCategoriesLimit(int top, Long userId, int peerAgeStart, int peerAgeEnd, - String peerGender); + List getTopConsumptionGoalCategories(Long userId, int peerAgeStart, int peerAgeEnd, + String peerGender); - Page getTopGoalCategories(Long userId, int peerAgeStart, int peerAgeEnd, - String peerGender, Pageable pageable); + List getAllConsumptionGoalCategories(Long userId, int peerAgeS, int peerAgeE, + String peerG); ConsumptionGoalResponseListDto findUserConsumptionGoalList(Long userId, LocalDate date); - PeerInfoResponseDTO getPeerInfo(Long userId, int peerAgeStart, int peerAgeEnd, String peerGender); + PeerInfoResponseDto getPeerInfo(Long userId, int peerAgeStart, int peerAgeEnd, String peerGender); ConsumptionGoalResponseListDto updateConsumptionGoals(Long userId, - ConsumptionGoalListRequestDto consumptionGoalListRequestDto); + ConsumptionGoalListRequestDto consumptionGoalListRequestDto); - ConsumptionAnalysisResponseDTO getTopCategoryAndConsumptionAmount(Long userId); + ConsumptionAnalysisResponseDto getTopCategoryAndConsumptionAmount(Long userId); void recalculateConsumptionAmount(Expense expense, ExpenseUpdateRequestDto request, User user); @@ -41,8 +40,9 @@ ConsumptionGoalResponseListDto updateConsumptionGoals(Long userId, void decreaseConsumeAmount(Long userId, Long categoryId, Long amount, LocalDate expenseDate); - List getTopConsumption(int top, Long userId, int peerAgeS, int peerAgeE, String peerG); + List getTopConsumptionCategories(Long userId, int peerAgeStart, int peerAgeEnd, + String peerGender); - Page getTopConsumptions(Long userId, int peerAgeS, int peerAgeE, - String peerG, Pageable pageable); + List getAllConsumptionCategories(Long userId, int peerAgeS, int peerAgeE, + String peerG); } diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceImpl.java b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceImpl.java index e3fbe04b..2f26f303 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceImpl.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceImpl.java @@ -4,32 +4,32 @@ import java.time.LocalDate; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Optional; +import java.util.function.Function; import java.util.stream.Collectors; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.bbteam.budgetbuddies.domain.category.entity.Category; import com.bbteam.budgetbuddies.domain.category.repository.CategoryRepository; -import com.bbteam.budgetbuddies.domain.consumptiongoal.converter.ConsumptionAnalysisConverter; import com.bbteam.budgetbuddies.domain.consumptiongoal.converter.ConsumptionGoalConverter; -import com.bbteam.budgetbuddies.domain.consumptiongoal.converter.PeerInfoConverter; -import com.bbteam.budgetbuddies.domain.consumptiongoal.converter.TopCategoryConverter; -import com.bbteam.budgetbuddies.domain.consumptiongoal.converter.TopConsumptionConverter; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AllConsumptionCategoryResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AvgConsumptionGoalDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.CategoryConsumptionCountDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalListRequestDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalRequestDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopConsumptionResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.MyConsumptionGoalDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopCategoryConsumptionDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; import com.bbteam.budgetbuddies.domain.consumptiongoal.repository.ConsumptionGoalRepository; import com.bbteam.budgetbuddies.domain.expense.dto.ExpenseUpdateRequestDto; @@ -62,68 +62,160 @@ public class ConsumptionGoalServiceImpl implements ConsumptionGoalService { @Override @Transactional(readOnly = true) - public List getTopGoalCategoriesLimit(int top, Long userId, int peerAgeS, int peerAgeE, String peerG) { + public List getTopConsumptionGoalCategories(Long userId, int peerAgeS, int peerAgeE, + String peerG) { + checkPeerInfo(userId, peerAgeS, peerAgeE, peerG); - List topGoals = consumptionGoalRepository.findTopCategoriesAndGoalAmountLimit(top, peerAgeStart, peerAgeEnd, peerGender, currentMonth); - return topGoals.stream().map(TopCategoryConverter::fromEntity).collect(Collectors.toList()); + + List categoryAvgList = getAvgGoalAmount(); + + return categoryAvgList.stream() + .sorted(Comparator.comparing(AvgConsumptionGoalDto::getAverageAmount).reversed()) + .limit(4) + .map(avgGoal -> TopGoalCategoryResponseDto.builder() + .categoryName(getCategoryNameById(avgGoal.getCategoryId())) + .goalAmount(avgGoal.getAverageAmount()) + .build()) + .collect(Collectors.toList()); } @Override @Transactional(readOnly = true) - public Page getTopGoalCategories(Long userId, int peerAgeS, int peerAgeE, String peerG, Pageable pageable) { + public List getAllConsumptionGoalCategories(Long userId, int peerAgeS, + int peerAgeE, String peerG) { + checkPeerInfo(userId, peerAgeS, peerAgeE, peerG); - Page topGoals = consumptionGoalRepository.findTopCategoriesAndGoalAmount(peerAgeStart, - peerAgeEnd, peerGender, currentMonth, pageable); - return topGoals.map(TopCategoryConverter::fromEntity); + + List categoryAvgList = getAvgGoalAmount(); + + List myConsumptionAmountList = getMyGoalAmount(userId); + + List defaultCategories = categoryRepository.findAllByIsDefaultTrue(); + return defaultCategories.stream() + .map(category -> { + MyConsumptionGoalDto myConsumptionAmountDto = myConsumptionAmountList.stream() + .filter(dto -> dto.getCategoryId().equals(category.getId())) + .findFirst() + .orElse(new MyConsumptionGoalDto(category.getId(), 0L)); + + AvgConsumptionGoalDto avgDto = categoryAvgList.stream() + .filter(dto -> dto.getCategoryId().equals(category.getId())) + .findFirst() + .orElse(new AvgConsumptionGoalDto(category.getId(), 0L)); + + Long avgConsumeAmount = avgDto.getAverageAmount(); + Long myConsumeAmount = myConsumptionAmountDto.getMyAmount(); + long consumeAmountDifference; + + if (avgConsumeAmount == 0L) { + consumeAmountDifference = -myConsumeAmount; + } else { + consumeAmountDifference = myConsumeAmount - avgConsumeAmount; + } + + return AllConsumptionCategoryResponseDto.builder() + .categoryName(category.getName()) + .avgAmount(avgConsumeAmount) + .amountDifference(consumeAmountDifference) + .build(); + }) + .collect(Collectors.toList()); + } @Override @Transactional(readOnly = true) - public PeerInfoResponseDTO getPeerInfo(Long userId, int peerAgeS, int peerAgeE, String peerG) { + public PeerInfoResponseDto getPeerInfo(Long userId, int peerAgeS, int peerAgeE, String peerG) { checkPeerInfo(userId, peerAgeS, peerAgeE, peerG); - return PeerInfoConverter.fromEntity(peerAgeStart, peerAgeEnd, peerGender); + return consumptionGoalConverter.toPeerInfo(peerAgeStart, peerAgeEnd, peerGender); } @Override @Transactional(readOnly = true) - public ConsumptionAnalysisResponseDTO getTopCategoryAndConsumptionAmount(Long userId) { + public ConsumptionAnalysisResponseDto getTopCategoryAndConsumptionAmount(Long userId) { checkPeerInfo(userId, 0, 0, "none"); - ConsumptionGoal topConsumptionGoal = consumptionGoalRepository.findTopCategoriesAndGoalAmountLimit(1, peerAgeStart, peerAgeEnd, peerGender, currentMonth).get(0); - - ConsumptionGoal currentWeekConsumptionAmount = consumptionGoalRepository.findTopConsumptionByCategoryIdAndCurrentWeek( - topConsumptionGoal.getCategory().getId(), startOfWeek, endOfWeek) - .orElseThrow(() -> new IllegalArgumentException( - "카테고리 ID " + topConsumptionGoal.getCategory().getId() + "에 대한 현재 주 소비 데이터가 없습니다.")); + List avgConsumptionGoalList = consumptionGoalRepository.findAvgGoalAmountByCategory( + peerAgeStart, + peerAgeEnd, peerGender, currentMonth); + + Long topConsumptionGoalCategoryId = avgConsumptionGoalList.get(0).getCategoryId(); - Long totalConsumptionAmountForCurrentWeek = currentWeekConsumptionAmount.getConsumeAmount(); + Long currentWeekConsumptionAmount = consumptionGoalRepository + .findAvgConsumptionByCategoryIdAndCurrentWeek(topConsumptionGoalCategoryId, startOfWeek, endOfWeek, + peerAgeStart, peerAgeEnd, peerGender) + .orElse(0L); - return ConsumptionAnalysisConverter.fromEntity(topConsumptionGoal, totalConsumptionAmountForCurrentWeek); + String topGoalCategory = getCategoryNameById(topConsumptionGoalCategoryId); + + return consumptionGoalConverter.toTopCategoryAndConsumptionAmount(topGoalCategory, + currentWeekConsumptionAmount); } @Override - public List getTopConsumptionsLimit(int top, Long userId, int peerAgeS, int peerAgeE, - String peerG) { + @Transactional(readOnly = true) + public List getTopConsumptionCategories(Long userId, int peerAgeS, int peerAgeE, + String peerG) { checkPeerInfo(userId, peerAgeS, peerAgeE, peerG); - List topConsumptions = consumptionGoalRepository.findTopConsumptionAndConsumeAmountLimit(top, - peerAgeStart, peerAgeEnd, peerGender, currentMonth); - return topConsumptions.stream().map(TopConsumptionConverter::fromEntity).collect(Collectors.toList()); + List categoryConsumptionCountDto = consumptionGoalRepository + .findTopCategoriesByConsumptionCount(peerAgeStart, peerAgeEnd, peerGender, currentMonth); + + return categoryConsumptionCountDto.stream() + .limit(3) + .map(category -> TopCategoryConsumptionDto.builder() + .categoryName(getCategoryNameById(category.getCategoryId())) + .consumptionCount(category.getConsumptionCount()) + .build()) + .collect(Collectors.toList()); } @Override - public Page getTopConsumptions(Long userId, int peerAgeS, int peerAgeE, String peerG, - Pageable pageable) { + @Transactional(readOnly = true) + public List getAllConsumptionCategories(Long userId, int peerAgeS, int peerAgeE, + String peerG) { checkPeerInfo(userId, peerAgeS, peerAgeE, peerG); - Page topConsumptions = consumptionGoalRepository.findTopConsumptionAndConsumeAmount( - peerAgeStart, peerAgeEnd, peerGender, currentMonth, pageable); - return topConsumptions.map(TopConsumptionConverter::fromEntity); + List categoryAvgList = getAvgConsumptionAmount(); + + List myConsumptionAmountList = getMyConsumptionAmount(userId); + + List defaultCategories = categoryRepository.findAllByIsDefaultTrue(); + + return defaultCategories.stream() + .map(category -> { + MyConsumptionGoalDto myConsumptionAmountDto = myConsumptionAmountList.stream() + .filter(dto -> dto.getCategoryId().equals(category.getId())) + .findFirst() + .orElse(new MyConsumptionGoalDto(category.getId(), 0L)); + + AvgConsumptionGoalDto avgDto = categoryAvgList.stream() + .filter(dto -> dto.getCategoryId().equals(category.getId())) + .findFirst() + .orElse(new AvgConsumptionGoalDto(category.getId(), 0L)); + + Long avgConsumeAmount = avgDto.getAverageAmount(); + Long myConsumeAmount = myConsumptionAmountDto.getMyAmount(); + long consumeAmountDifference; + + if (avgConsumeAmount == 0L) { + consumeAmountDifference = -myConsumeAmount; + } else { + consumeAmountDifference = myConsumeAmount - avgConsumeAmount; + } + + return AllConsumptionCategoryResponseDto.builder() + .categoryName(category.getName()) + .avgAmount(avgConsumeAmount) + .amountDifference(consumeAmountDifference) + .build(); + }) + .collect(Collectors.toList()); } private User findUserById(Long userId) { @@ -171,31 +263,117 @@ private void setAgeGroupByUser(int userAge) { } } + private List getAvgConsumptionAmount() { + + List defaultCategories = categoryRepository.findAllByIsDefaultTrue(); + List categoryAvgList = new ArrayList<>(); + + List avgConsumptionGoalDto = consumptionGoalRepository + .findAvgConsumptionAmountByCategory(peerAgeStart, peerAgeEnd, peerGender, currentMonth); + + Map categoryAvgMap = avgConsumptionGoalDto.stream() + .collect(Collectors.toMap(AvgConsumptionGoalDto::getCategoryId, Function.identity())); + + for (Category category : defaultCategories) { + AvgConsumptionGoalDto avgDto = categoryAvgMap.getOrDefault(category.getId(), + new AvgConsumptionGoalDto(category.getId(), 0.0)); + + categoryAvgList.add(avgDto); + } + return categoryAvgList; + } + + private List getMyConsumptionAmount(Long userId) { + + List defaultCategories = categoryRepository.findAllByIsDefaultTrue(); + List myConsumptionAmountList = new ArrayList<>(); + + List myConsumptionGoalDto = consumptionGoalRepository.findAllConsumptionAmountByUserId( + userId); + + Map myConsumptionMap = myConsumptionGoalDto.stream() + .collect(Collectors.toMap(MyConsumptionGoalDto::getCategoryId, Function.identity())); + + for (Category category : defaultCategories) { + MyConsumptionGoalDto myConsumptionGaolDto = myConsumptionMap.getOrDefault(category.getId(), + new MyConsumptionGoalDto(category.getId(), 0L)); + + myConsumptionAmountList.add(myConsumptionGaolDto); + } + return myConsumptionAmountList; + } + + private List getAvgGoalAmount() { + + List defaultCategories = categoryRepository.findAllByIsDefaultTrue(); + List categoryAvgList = new ArrayList<>(); + + List avgConsumptionGoalDto = consumptionGoalRepository.findAvgGoalAmountByCategory( + peerAgeStart, peerAgeEnd, peerGender, currentMonth); + + Map categoryAvgMap = avgConsumptionGoalDto.stream() + .collect(Collectors.toMap(AvgConsumptionGoalDto::getCategoryId, Function.identity())); + + for (Category category : defaultCategories) { + AvgConsumptionGoalDto avgDto = categoryAvgMap.getOrDefault(category.getId(), + new AvgConsumptionGoalDto(category.getId(), 0.0)); + + categoryAvgList.add(avgDto); + } + return categoryAvgList; + } + + private List getMyGoalAmount(Long userId) { + + List defaultCategories = categoryRepository.findAllByIsDefaultTrue(); + List myConsumptionAmountList = new ArrayList<>(); + + List myConsumptionGoalDto = consumptionGoalRepository.findAllGoalAmountByUserId( + userId); + + Map myConsumptionMap = myConsumptionGoalDto.stream() + .collect(Collectors.toMap(MyConsumptionGoalDto::getCategoryId, Function.identity())); + + for (Category category : defaultCategories) { + MyConsumptionGoalDto myDto = myConsumptionMap.getOrDefault(category.getId(), + new MyConsumptionGoalDto(category.getId(), 0L)); + + myConsumptionAmountList.add(myDto); + } + return myConsumptionAmountList; + } + + private String getCategoryNameById(Long categoryId) { + Category category = categoryRepository.findById(categoryId) + .orElseThrow(() -> new RuntimeException("카테고리 " + categoryId + "를 찾을 수 없습니다.: ")); + return category.getName(); + } + @Override @Transactional public ConsumptionGoalResponseListDto updateConsumptionGoals(Long userId, - ConsumptionGoalListRequestDto consumptionGoalListRequestDto) { + ConsumptionGoalListRequestDto consumptionGoalListRequestDto) { LocalDate thisMonth = LocalDate.now().withDayOfMonth(1); User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("Not found user")); List updatedConsumptionGoal = consumptionGoalListRequestDto.getConsumptionGoalList() - .stream() - .map(c -> updateConsumptionGoalWithRequestDto(user, c, thisMonth)) - .toList(); + .stream() + .map(c -> updateConsumptionGoalWithRequestDto(user, c, thisMonth)) + .toList(); List response = consumptionGoalRepository.saveAll(updatedConsumptionGoal) - .stream() - .map(consumptionGoalConverter::toConsumptionGoalResponseDto) - .toList(); + .stream() + .map(consumptionGoalConverter::toConsumptionGoalResponseDto) + .toList(); return consumptionGoalConverter.toConsumptionGoalResponseListDto(response, thisMonth); } private ConsumptionGoal updateConsumptionGoalWithRequestDto(User user, - ConsumptionGoalRequestDto consumptionGoalRequestDto, LocalDate goalMonth) { + ConsumptionGoalRequestDto consumptionGoalRequestDto, LocalDate goalMonth) { Category category = categoryRepository.findById(consumptionGoalRequestDto.getCategoryId()) - .orElseThrow(() -> new IllegalArgumentException("Not found Category")); + .orElseThrow(() -> new IllegalArgumentException("Not found Category")); ConsumptionGoal consumptionGoal = findOrElseGenerateConsumptionGoal(user, category, goalMonth); consumptionGoal.updateGoalAmount(consumptionGoalRequestDto.getGoalAmount()); @@ -205,17 +383,17 @@ private ConsumptionGoal updateConsumptionGoalWithRequestDto(User user, private ConsumptionGoal findOrElseGenerateConsumptionGoal(User user, Category category, LocalDate goalMonth) { return consumptionGoalRepository.findConsumptionGoalByUserAndCategoryAndGoalMonth(user, category, goalMonth) - .orElseGet(() -> generateNewConsumptionGoal(user, category, goalMonth)); + .orElseGet(() -> generateNewConsumptionGoal(user, category, goalMonth)); } private ConsumptionGoal generateNewConsumptionGoal(User user, Category category, LocalDate goalMonth) { return ConsumptionGoal.builder() - .goalMonth(goalMonth) - .user(user) - .category(category) - .consumeAmount(0L) - .goalAmount(0L) - .build(); + .goalMonth(goalMonth) + .user(user) + .category(category) + .consumeAmount(0L) + .goalAmount(0L) + .build(); } @Override @@ -232,25 +410,25 @@ public ConsumptionGoalResponseListDto findUserConsumptionGoalList(Long userId, L private Map initializeGoalMap(Long userId) { return categoryRepository.findUserCategoryByUserId(userId) - .stream() - .collect(Collectors.toMap(Category::getId, consumptionGoalConverter::toConsumptionGoalResponseDto)); + .stream() + .collect(Collectors.toMap(Category::getId, consumptionGoalConverter::toConsumptionGoalResponseDto)); } private void updateGoalMapWithPreviousMonth(Long userId, LocalDate goalMonth, - Map goalMap) { + Map goalMap) { updateGoalMap(userId, goalMonth.minusMonths(1), goalMap); } private void updateGoalMapWithCurrentMonth(Long userId, LocalDate goalMonth, - Map goalMap) { + Map goalMap) { updateGoalMap(userId, goalMonth, goalMap); } private void updateGoalMap(Long userId, LocalDate month, Map goalMap) { consumptionGoalRepository.findConsumptionGoalByUserIdAndGoalMonth(userId, month) - .stream() - .map(consumptionGoalConverter::toConsumptionGoalResponseDto) - .forEach(goal -> goalMap.put(goal.getCategoryId(), goal)); + .stream() + .map(consumptionGoalConverter::toConsumptionGoalResponseDto) + .forEach(goal -> goalMap.put(goal.getCategoryId(), goal)); } @Override @@ -262,8 +440,8 @@ public void recalculateConsumptionAmount(Expense expense, ExpenseUpdateRequestDt private void restorePreviousGoalConsumptionAmount(Expense expense, User user) { ConsumptionGoal previousConsumptionGoal = consumptionGoalRepository.findConsumptionGoalByUserAndCategoryAndGoalMonth( - user, expense.getCategory(), expense.getExpenseDate().toLocalDate().withDayOfMonth(1)) - .orElseThrow(() -> new IllegalArgumentException("Not found consumptionGoal")); + user, expense.getCategory(), expense.getExpenseDate().toLocalDate().withDayOfMonth(1)) + .orElseThrow(() -> new IllegalArgumentException("Not found consumptionGoal")); previousConsumptionGoal.restoreConsumeAmount(expense.getAmount()); consumptionGoalRepository.save(previousConsumptionGoal); @@ -271,12 +449,12 @@ private void restorePreviousGoalConsumptionAmount(Expense expense, User user) { private void calculatePresentGoalConsumptionAmount(ExpenseUpdateRequestDto request, User user) { Category categoryToReplace = categoryRepository.findById(request.getCategoryId()) - .orElseThrow(() -> new IllegalArgumentException("Not found category")); + .orElseThrow(() -> new IllegalArgumentException("Not found category")); ConsumptionGoal consumptionGoal = consumptionGoalRepository.findConsumptionGoalByUserAndCategoryAndGoalMonth( - user, categoryToReplace, request.getExpenseDate().toLocalDate().withDayOfMonth(1)) - .orElseGet(() -> this.generateGoalByPreviousOrElseNew(user, categoryToReplace, - request.getExpenseDate().toLocalDate().withDayOfMonth(1))); + user, categoryToReplace, request.getExpenseDate().toLocalDate().withDayOfMonth(1)) + .orElseGet(() -> this.generateGoalByPreviousOrElseNew(user, categoryToReplace, + request.getExpenseDate().toLocalDate().withDayOfMonth(1))); consumptionGoal.updateConsumeAmount(request.getAmount()); consumptionGoalRepository.save(consumptionGoal); @@ -286,18 +464,18 @@ private ConsumptionGoal generateGoalByPreviousOrElseNew(User user, Category cate LocalDate previousMonth = goalMonth.minusMonths(1); return consumptionGoalRepository.findConsumptionGoalByUserAndCategoryAndGoalMonth(user, category, previousMonth) - .map(this::generateGoalByPrevious) - .orElseGet(() -> generateNewConsumptionGoal(user, category, goalMonth)); + .map(this::generateGoalByPrevious) + .orElseGet(() -> generateNewConsumptionGoal(user, category, goalMonth)); } private ConsumptionGoal generateGoalByPrevious(ConsumptionGoal consumptionGoal) { return ConsumptionGoal.builder() - .goalMonth(consumptionGoal.getGoalMonth().plusMonths(1)) - .user(consumptionGoal.getUser()) - .category(consumptionGoal.getCategory()) - .consumeAmount(0L) - .goalAmount(consumptionGoal.getGoalAmount()) - .build(); + .goalMonth(consumptionGoal.getGoalMonth().plusMonths(1)) + .user(consumptionGoal.getUser()) + .category(consumptionGoal.getCategory()) + .consumeAmount(0L) + .goalAmount(consumptionGoal.getGoalAmount()) + .build(); } @Override @@ -305,41 +483,30 @@ public void updateConsumeAmount(Long userId, Long categoryId, Long amount) { User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("Not found user")); Category category = categoryRepository.findById(categoryId) - .orElseThrow(() -> new IllegalArgumentException("Not found Category")); + .orElseThrow(() -> new IllegalArgumentException("Not found Category")); LocalDate thisMonth = LocalDate.now().withDayOfMonth(1); ConsumptionGoal consumptionGoal = consumptionGoalRepository.findConsumptionGoalByUserAndCategoryAndGoalMonth( - user, category, thisMonth).orElseGet(() -> generateNewConsumptionGoal(user, category, thisMonth)); + user, category, thisMonth).orElseGet(() -> generateNewConsumptionGoal(user, category, thisMonth)); consumptionGoal.updateConsumeAmount(amount); consumptionGoalRepository.save(consumptionGoal); } - @Override - public List getTopConsumption(int top, Long userId, int peerAgeS, int peerAgeE, - String peerG) { - - checkPeerInfo(userId, peerAgeS, peerAgeE, peerG); - - List topConsumptions = consumptionGoalRepository.findTopConsumptionAndConsumeAmount(top, - peerAgeStart, peerAgeEnd, peerGender); - return topConsumptions.stream().map(TopConsumptionConverter::fromEntity).collect(Collectors.toList()); - } - @Override public void decreaseConsumeAmount(Long userId, Long categoryId, Long amount, LocalDate expenseDate) { User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("Not found user")); + .orElseThrow(() -> new IllegalArgumentException("Not found user")); Category category = categoryRepository.findById(categoryId) - .orElseThrow(() -> new IllegalArgumentException("Not found Category")); + .orElseThrow(() -> new IllegalArgumentException("Not found Category")); LocalDate goalMonth = expenseDate.withDayOfMonth(1); ConsumptionGoal consumptionGoal = consumptionGoalRepository - .findConsumptionGoalByUserAndCategoryAndGoalMonth(user, category, goalMonth) - .orElseThrow(() -> new IllegalArgumentException("Not found ConsumptionGoal")); + .findConsumptionGoalByUserAndCategoryAndGoalMonth(user, category, goalMonth) + .orElseThrow(() -> new IllegalArgumentException("Not found ConsumptionGoal")); consumptionGoal.decreaseConsumeAmount(amount); consumptionGoalRepository.save(consumptionGoal); } -} +} \ No newline at end of file diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/converter/MainPageConverter.java b/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/converter/MainPageConverter.java index 02a7e32b..7bee8e6a 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/converter/MainPageConverter.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/converter/MainPageConverter.java @@ -1,24 +1,24 @@ package com.bbteam.budgetbuddies.domain.mainpage.converter; +import java.util.List; + +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; import com.bbteam.budgetbuddies.domain.discountinfo.dto.DiscountResponseDto; import com.bbteam.budgetbuddies.domain.mainpage.dto.MainPageResponseDto; import com.bbteam.budgetbuddies.domain.supportinfo.dto.SupportResponseDto; -import java.util.List; - public class MainPageConverter { - public static MainPageResponseDto toMainPageResponseDto( - List discountResponseDtoList, - List supportResponseDtoList, - TopGoalCategoryResponseDTO topGoalCategoryResponseDTO, - ConsumptionGoalResponseListDto consumptionGoalResponseListDto) { - return MainPageResponseDto.builder() - .discountResponseDtoList(discountResponseDtoList) - .supportResponseDtoList(supportResponseDtoList) - .topGoalCategoryResponseDTO(topGoalCategoryResponseDTO) - .consumptionGoalResponseListDto(consumptionGoalResponseListDto) - .build(); - } + public static MainPageResponseDto toMainPageResponseDto( + List discountResponseDtoList, + List supportResponseDtoList, + ConsumptionAnalysisResponseDto consumptionAnalysisResponseDto, + ConsumptionGoalResponseListDto consumptionGoalResponseListDto) { + return MainPageResponseDto.builder() + .discountResponseDtoList(discountResponseDtoList) + .supportResponseDtoList(supportResponseDtoList) + .consumptionAnalysisResponseDto(consumptionAnalysisResponseDto) + .consumptionGoalResponseListDto(consumptionGoalResponseListDto) + .build(); + } } diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/dto/MainPageResponseDto.java b/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/dto/MainPageResponseDto.java index 2031c2d3..ec371c18 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/dto/MainPageResponseDto.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/dto/MainPageResponseDto.java @@ -1,22 +1,23 @@ package com.bbteam.budgetbuddies.domain.mainpage.dto; +import java.util.List; + +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; import com.bbteam.budgetbuddies.domain.discountinfo.dto.DiscountResponseDto; import com.bbteam.budgetbuddies.domain.supportinfo.dto.SupportResponseDto; + import lombok.Builder; import lombok.Getter; -import java.util.List; - @Getter @Builder public class MainPageResponseDto { - private TopGoalCategoryResponseDTO topGoalCategoryResponseDTO; - private ConsumptionGoalResponseListDto consumptionGoalResponseListDto; - private List discountResponseDtoList; - private List supportResponseDtoList; - // 기존 DTO들 활용 + private ConsumptionAnalysisResponseDto consumptionAnalysisResponseDto; + private ConsumptionGoalResponseListDto consumptionGoalResponseListDto; + private List discountResponseDtoList; + private List supportResponseDtoList; + // 기존 DTO들 활용 } diff --git a/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/service/MainPageServiceImpl.java b/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/service/MainPageServiceImpl.java index b5089589..fd3b0b9c 100644 --- a/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/service/MainPageServiceImpl.java +++ b/src/main/java/com/bbteam/budgetbuddies/domain/mainpage/service/MainPageServiceImpl.java @@ -2,12 +2,11 @@ import java.time.LocalDate; import java.util.List; -import java.util.NoSuchElementException; import org.springframework.stereotype.Service; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; import com.bbteam.budgetbuddies.domain.consumptiongoal.service.ConsumptionGoalService; import com.bbteam.budgetbuddies.domain.discountinfo.dto.DiscountResponseDto; import com.bbteam.budgetbuddies.domain.discountinfo.service.DiscountInfoService; @@ -36,17 +35,12 @@ public MainPageResponseDto getMainPage(Long userId) { now.getMonthValue(), 0, 2) .getContent(); - List topGoalCategoryResponseDTOList = consumptionGoalService.getTopGoalCategoriesLimit( - 1, userId, 0, 0, "NONE"); - if (topGoalCategoryResponseDTOList.size() == 0) { - throw new NoSuchElementException("Category xx"); - } - TopGoalCategoryResponseDTO topGoalCategoryResponseDTO = topGoalCategoryResponseDTOList.get(0); + ConsumptionAnalysisResponseDto responseDto = consumptionGoalService.getTopCategoryAndConsumptionAmount(userId); ConsumptionGoalResponseListDto userConsumptionGoal = consumptionGoalService.findUserConsumptionGoalList(userId, now); return MainPageConverter.toMainPageResponseDto(discountResponseDtoList, supportResponseDtoList, - topGoalCategoryResponseDTO, userConsumptionGoal); + responseDto, userConsumptionGoal); } } diff --git a/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepositoryTest.java b/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepositoryTest.java index 360c66ce..054b35de 100644 --- a/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepositoryTest.java +++ b/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/repository/ConsumptionGoalRepositoryTest.java @@ -4,8 +4,8 @@ import java.time.LocalDate; import java.util.List; -import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -14,6 +14,9 @@ import com.bbteam.budgetbuddies.domain.category.entity.Category; import com.bbteam.budgetbuddies.domain.category.repository.CategoryRepository; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AvgConsumptionGoalDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.CategoryConsumptionCountDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.MyConsumptionGoalDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; import com.bbteam.budgetbuddies.domain.user.entity.User; import com.bbteam.budgetbuddies.domain.user.repository.UserRepository; @@ -30,7 +33,67 @@ class ConsumptionGoalRepositoryTest { @Autowired CategoryRepository categoryRepository; - LocalDate currentMonth = LocalDate.now().withDayOfMonth(1); + private User peerUser1; + private User peerUser2; + private Category defaultCategory1; + private Category defaultCategory2; + private LocalDate currentMonth; + + @BeforeEach + void setUp() { + defaultCategory1 = categoryRepository.save( + Category.builder().name("Category 1").user(null).isDefault(true).build()); + + defaultCategory2 = categoryRepository.save( + Category.builder().name("Category 2").user(null).isDefault(true).build()); + + peerUser1 = userRepository.save( + User.builder() + .email("peer1@example.com") + .age(24) + .name("Peer User 1") + .gender(Gender.MALE) + .phoneNumber("010-1111-1111") + .build()); + + peerUser2 = userRepository.save( + User.builder() + .email("peer2@example.com") + .age(25) + .name("Peer User 2") + .gender(Gender.MALE) + .phoneNumber("010-2222-2222") + .build()); + + currentMonth = LocalDate.now(); + + consumptionGoalRepository.save( + ConsumptionGoal.builder() + .goalAmount(100L) + .consumeAmount(50L) + .user(peerUser1) + .category(defaultCategory1) + .goalMonth(currentMonth) + .build()); + + consumptionGoalRepository.save( + ConsumptionGoal.builder() + .goalAmount(150L) + .consumeAmount(100L) + .user(peerUser1) + .category(defaultCategory2) + .goalMonth(currentMonth) + .build()); + + consumptionGoalRepository.save( + ConsumptionGoal.builder() + .goalAmount(200L) + .consumeAmount(150L) + .user(peerUser2) + .category(defaultCategory2) + .goalMonth(currentMonth) + .build()); + } @Test @DisplayName("유저 아이디와 goalMonth를 통해 GoalConsumption 조회 성공") @@ -77,95 +140,52 @@ void findConsumptionGoalByUserIdAndGoalMonth_Success() { } @Test - @DisplayName("또래 나이와 성별 정보를 통해 GoalConsumption 조회 성공") - void findTopCategoriesAndGoalAmount_Success() { - //given - User mainUser = userRepository.save( - User.builder() - .email("email") - .age(24) - .name("name") - .gender(Gender.MALE) - .phoneNumber("010-1234-5678") - .build()); - - Category defaultCategory = categoryRepository.save( - Category.builder().name("디폴트 카테고리").user(null).isDefault(true).build()); - - LocalDate goalMonth = LocalDate.now(); - - ConsumptionGoal defaultCategoryConsumptionGoal = consumptionGoalRepository.save(ConsumptionGoal.builder() - .goalAmount(1L) - .consumeAmount(1L) - .user(mainUser) - .goalMonth(goalMonth) - .category(defaultCategory) - .build()); - + @DisplayName("또래 나이와 성별 정보를 통해 카테고리와 평균 소비 금액 조회 성공") + void findAvgConsumptionAmountByCategory_Success() { // when - int top = 4; int peerAgeStart = 23; int peerAgeEnd = 25; Gender peerGender = Gender.MALE; - List result = consumptionGoalRepository.findTopCategoriesAndGoalAmountLimit( - top, peerAgeStart, peerAgeEnd, peerGender, currentMonth); + List result = consumptionGoalRepository.findAvgConsumptionAmountByCategory( + peerAgeStart, peerAgeEnd, peerGender, currentMonth); // then - ConsumptionGoal resultGoal = result.get(0); - assertThat(resultGoal.getGoalAmount()).isEqualTo(1L); - assertThat(resultGoal.getConsumeAmount()).isEqualTo(1L); - assertThat(resultGoal.getUser().getAge()).isEqualTo(24); - assertThat(resultGoal.getCategory().getName()).isEqualTo("디폴트 카테고리"); - assertThat(resultGoal.getUser().getGender()).isEqualTo(Gender.MALE); + assertThat(result).isNotEmpty(); + + AvgConsumptionGoalDto resultGoal1 = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory1.getId())) + .findFirst() + .orElseThrow(); + assertThat(resultGoal1.getAverageAmount()).isEqualTo(50L); + + AvgConsumptionGoalDto resultGoal2 = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory2.getId())) + .findFirst() + .orElseThrow(); + assertThat(resultGoal2.getAverageAmount()).isEqualTo(125L); } @Test - @DisplayName("또래들이 가장 큰 목표로 세운 카테고리와 그 카테고리에서 이번 주의 소비 목표 조회 성공") - void findTopConsumptionByCategoryIdAndCurrentWeek_Success() { - // given - LocalDate startOfWeek = LocalDate.of(2024, 7, 1); // 월요일 - LocalDate endOfWeek = LocalDate.of(2024, 7, 7); // 일요일 - - User mainUser = userRepository.save(User.builder() - .email("email") - .age(24) - .name("name") - .gender(Gender.MALE) - .phoneNumber("010-1234-5678") - .build()); + @DisplayName("또래 나이와 성별 정보를 통해 카테고리와 나의 소비 금액 조회 성공") + void findAllConsumptionAmountByUserId_Success() { + // when + List result = consumptionGoalRepository.findAllConsumptionAmountByUserId( + peerUser1.getId()); - Category category = categoryRepository.save(Category.builder() - .name("Test Category") - .user(mainUser) - .isDefault(false) - .build()); + // then + assertThat(result).isNotEmpty(); - ConsumptionGoal goal1 = consumptionGoalRepository.save(ConsumptionGoal.builder() - .goalAmount(5000L) - .consumeAmount(2000L) - .user(mainUser) - .category(category) - .goalMonth(startOfWeek) - .build()); + Long categoryId1 = defaultCategory1.getId(); - ConsumptionGoal goal2 = consumptionGoalRepository.save(ConsumptionGoal.builder() - .goalAmount(3000L) - .consumeAmount(1500L) - .user(mainUser) - .category(category) - .goalMonth(startOfWeek) - .build()); + MyConsumptionGoalDto firstResult = result.stream() + .filter(dto -> dto.getCategoryId().equals(categoryId1)) + .findFirst() + .orElseThrow(() -> new AssertionError("Category ID " + categoryId1 + " not found")); - // when - Optional result = consumptionGoalRepository.findTopConsumptionByCategoryIdAndCurrentWeek( - category.getId(), startOfWeek, endOfWeek); + assertThat(firstResult.getCategoryId()).isEqualTo(categoryId1); + assertThat(firstResult.getMyAmount()).isEqualTo(50L); - // then - ConsumptionGoal topGoal = result.get(); - assertThat(topGoal.getConsumeAmount()).isEqualTo(2000L); - assertThat(topGoal.getGoalAmount()).isEqualTo(5000L); - assertThat(topGoal.getCategory().getId()).isEqualTo(category.getId()); } private void setUnselectedConsumptionGoal(User mainUser, LocalDate goalMonth, Category defaultCategory) { @@ -192,46 +212,82 @@ private void setUnselectedConsumptionGoal(User mainUser, LocalDate goalMonth, Ca } @Test - @DisplayName("또래 나이와 성별 정보를 통해 GoalConsumption 조회 성공") - void findTopConsumptionAndConsumeAmount_Success() { - //given - User mainUser = userRepository.save( - User.builder() - .email("email") - .age(24) - .name("name") - .gender(Gender.MALE) - .phoneNumber("010-1234-5678") - .build()); + @DisplayName("또래 나이와 성별 정보를 통해 카테고리와 평균 목표 금액 조회 성공") + void findAvgGoalAmountByCategory_Success() { + // when + int peerAgeStart = 23; + int peerAgeEnd = 25; + Gender peerGender = Gender.MALE; - Category defaultCategory = categoryRepository.save( - Category.builder().name("디폴트 카테고리").user(null).isDefault(true).build()); + List result = consumptionGoalRepository.findAvgGoalAmountByCategory( + peerAgeStart, peerAgeEnd, peerGender, currentMonth); - LocalDate goalMonth = LocalDate.now(); + // then + assertThat(result).isNotEmpty(); - ConsumptionGoal defaultCategoryConsumptionGoal = consumptionGoalRepository.save(ConsumptionGoal.builder() - .goalAmount(1L) - .consumeAmount(1L) - .user(mainUser) - .goalMonth(goalMonth) - .category(defaultCategory) - .build()); + AvgConsumptionGoalDto firstResult = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory1.getId())) + .findFirst() + .orElseThrow(() -> new AssertionError("Category ID " + defaultCategory1.getId() + " not found")); + + AvgConsumptionGoalDto secondResult = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory2.getId())) + .findFirst() + .orElseThrow(() -> new AssertionError("Category ID " + defaultCategory2.getId() + " not found")); + assertThat(firstResult.getAverageAmount()).isEqualTo(100L); + assertThat(secondResult.getAverageAmount()).isEqualTo(175L); + } + + @Test + @DisplayName("또래 나이와 성별 정보를 통해 카테고리와 평균 목표 금액 조회 성공") + void findAllGoalAmountByUserId_Success() { + // when + List result = consumptionGoalRepository.findAllGoalAmountByUserId(peerUser1.getId()); + + // then + assertThat(result).isNotEmpty(); + + MyConsumptionGoalDto firstResult = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory1.getId())) + .findFirst() + .orElseThrow(() -> new AssertionError("Category ID " + defaultCategory1.getId() + " not found")); + + MyConsumptionGoalDto secondResult = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory2.getId())) + .findFirst() + .orElseThrow(() -> new AssertionError("Category ID " + defaultCategory2.getId() + " not found")); + + assertThat(firstResult.getMyAmount()).isEqualTo(100L); + assertThat(secondResult.getMyAmount()).isEqualTo(150L); + } + + @Test + @DisplayName("또래 나이와 성별 정보를 통해 카테고리별 소비 횟수 조회 성공") + void findTopCategoriesByConsumptionCount_Success() { // when - int top = 4; int peerAgeStart = 23; int peerAgeEnd = 25; Gender peerGender = Gender.MALE; + LocalDate currentMonth = LocalDate.now(); - List result = consumptionGoalRepository.findTopConsumptionAndConsumeAmountLimit( - top, peerAgeStart, peerAgeEnd, peerGender, currentMonth); + List result = consumptionGoalRepository.findTopCategoriesByConsumptionCount( + peerAgeStart, peerAgeEnd, peerGender, currentMonth); // then - ConsumptionGoal resultGoal = result.get(0); - assertThat(resultGoal.getGoalAmount()).isEqualTo(1L); - assertThat(resultGoal.getConsumeAmount()).isEqualTo(1L); - assertThat(resultGoal.getUser().getAge()).isEqualTo(24); - assertThat(resultGoal.getCategory().getName()).isEqualTo("디폴트 카테고리"); - assertThat(resultGoal.getUser().getGender()).isEqualTo(Gender.MALE); + assertThat(result).isNotEmpty(); + + CategoryConsumptionCountDto firstResult = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory1.getId())) + .findFirst() + .orElseThrow(() -> new AssertionError("Category ID " + defaultCategory1.getId() + " not found")); + + CategoryConsumptionCountDto secondResult = result.stream() + .filter(dto -> dto.getCategoryId().equals(defaultCategory2.getId())) + .findFirst() + .orElseThrow(() -> new AssertionError("Category ID " + defaultCategory2.getId() + " not found")); + + assertThat(firstResult.getConsumptionCount()).isEqualTo(1); + assertThat(secondResult.getConsumptionCount()).isEqualTo(2); } } \ No newline at end of file diff --git a/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceTest.java b/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceTest.java index 3a2af1eb..3b22aa79 100644 --- a/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceTest.java +++ b/src/test/java/com/bbteam/budgetbuddies/domain/consumptiongoal/service/ConsumptionGoalServiceTest.java @@ -26,14 +26,17 @@ import com.bbteam.budgetbuddies.domain.category.entity.Category; import com.bbteam.budgetbuddies.domain.category.repository.CategoryRepository; import com.bbteam.budgetbuddies.domain.consumptiongoal.converter.ConsumptionGoalConverter; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AllConsumptionCategoryResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.AvgConsumptionGoalDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.CategoryConsumptionCountDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionAnalysisResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalListRequestDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalRequestDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.ConsumptionGoalResponseListDto; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopConsumptionResponseDTO; -import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopGoalCategoryResponseDTO; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.MyConsumptionGoalDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.PeerInfoResponseDto; +import com.bbteam.budgetbuddies.domain.consumptiongoal.dto.TopCategoryConsumptionDto; import com.bbteam.budgetbuddies.domain.consumptiongoal.entity.ConsumptionGoal; import com.bbteam.budgetbuddies.domain.consumptiongoal.repository.ConsumptionGoalRepository; import com.bbteam.budgetbuddies.domain.expense.dto.ExpenseUpdateRequestDto; @@ -258,7 +261,7 @@ void getPeerInfo_Success() { int peerAgeEnd = 25; String peerGender = "MALE"; - PeerInfoResponseDTO result = consumptionGoalService.getPeerInfo(user.getId(), peerAgeStart, peerAgeEnd, + PeerInfoResponseDto result = consumptionGoalService.getPeerInfo(user.getId(), peerAgeStart, peerAgeEnd, peerGender); // then @@ -289,10 +292,16 @@ void getPeerInfo_UserNotFound() { @DisplayName("getTopCategoryAndConsumptionAmount : 가장 큰 계획 카테고리와 이번 주 소비 금액 조회 성공") void getTopCategoryAndConsumptionAmount_Success() { // given - Category defaultCategory = Mockito.spy(Category.builder().name("디폴트 카테고리").user(null).isDefault(true).build()); - given(defaultCategory.getId()).willReturn(-1L); + Category defaultCategory = Mockito.spy(Category.builder() + .name("디폴트 카테고리") + .user(null) + .isDefault(true) + .build()); + given(defaultCategory.getId()).willReturn(1L); LocalDate goalMonthRandomDay = LocalDate.now(); + LocalDate startOfWeek = goalMonthRandomDay.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); + LocalDate endOfWeek = goalMonthRandomDay.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); ConsumptionGoal topConsumptionGoal = ConsumptionGoal.builder() .goalAmount(5000L) @@ -310,19 +319,29 @@ void getTopCategoryAndConsumptionAmount_Success() { .goalMonth(goalMonthRandomDay) .build(); - LocalDate startOfWeek = goalMonthRandomDay.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); - LocalDate endOfWeek = goalMonthRandomDay.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY)); + List avgConsumptionGoalList = List.of( + new AvgConsumptionGoalDto(defaultCategory.getId(), 5000L) + ); + + int peerAgeStart = 23; + int peerAgeEnd = 25; + Gender peerGender = Gender.MALE; given(userRepository.findById(user.getId())).willReturn(Optional.of(user)); - given(consumptionGoalRepository.findTopCategoriesAndGoalAmountLimit(1, 23, 25, Gender.MALE, - currentMonth)).willReturn( - List.of(topConsumptionGoal)); - given( - consumptionGoalRepository.findTopConsumptionByCategoryIdAndCurrentWeek(defaultCategory.getId(), startOfWeek, - endOfWeek)).willReturn(Optional.of(currentWeekConsumptionGoal)); + given(consumptionGoalRepository.findAvgGoalAmountByCategory( + peerAgeStart, peerAgeEnd, peerGender, currentMonth)) + .willReturn(avgConsumptionGoalList); + + given(consumptionGoalRepository.findAvgConsumptionByCategoryIdAndCurrentWeek( + defaultCategory.getId(), startOfWeek, endOfWeek, + peerAgeStart, peerAgeEnd, peerGender)) + .willReturn(Optional.of(currentWeekConsumptionGoal.getConsumeAmount())); + + given(categoryRepository.findById(defaultCategory.getId())) + .willReturn(Optional.of(defaultCategory)); // when - ConsumptionAnalysisResponseDTO result = consumptionGoalService.getTopCategoryAndConsumptionAmount(user.getId()); + ConsumptionAnalysisResponseDto result = consumptionGoalService.getTopCategoryAndConsumptionAmount(user.getId()); // then assertThat(result.getGoalCategory()).isEqualTo(defaultCategory.getName()); @@ -330,121 +349,156 @@ void getTopCategoryAndConsumptionAmount_Success() { } @Test - @DisplayName("getTopGoalCategories : 또래들이 세운 가장 큰 목표 카테고리 조회 top 4 성공") - void getTopGoalCategories_Success() { + @DisplayName("getTopConsumptionCategories : 또래들이 가장 많이 소비한 카테고리 top3 조회 성공") + void getTopConsumptionCategories_Success() { // given - Category defaultCategory = Mockito.spy(Category.builder().name("디폴트 카테고리").user(null).isDefault(true).build()); - Category defaultCategory2 = Mockito.spy( - Category.builder().name("디폴트 카테고리2").user(null).isDefault(true).build()); - Category defaultCategory3 = Mockito.spy( - Category.builder().name("디폴트 카테고리3").user(null).isDefault(true).build()); - Category defaultCategory4 = Mockito.spy( - Category.builder().name("디폴트 카테고리4").user(null).isDefault(true).build()); - - ConsumptionGoal topConsumptionGoal1 = ConsumptionGoal.builder() - .goalAmount(5000L) - .consumeAmount(3000L) - .user(user) - .category(defaultCategory) - .goalMonth(goalMonthRandomDay) - .build(); + Category defaultCategory1 = Mockito.mock(Category.class); + Category defaultCategory2 = Mockito.mock(Category.class); + Category defaultCategory3 = Mockito.mock(Category.class); - ConsumptionGoal topConsumptionGoal2 = ConsumptionGoal.builder() - .goalAmount(6000L) - .consumeAmount(3000L) - .user(user) - .category(defaultCategory2) - .goalMonth(goalMonthRandomDay) - .build(); + given(defaultCategory1.getId()).willReturn(1L); + given(defaultCategory2.getId()).willReturn(2L); + given(defaultCategory3.getId()).willReturn(3L); - ConsumptionGoal topConsumptionGoal3 = ConsumptionGoal.builder() - .goalAmount(7000L) - .consumeAmount(3000L) - .user(user) - .category(defaultCategory3) - .goalMonth(goalMonthRandomDay) - .build(); + given(defaultCategory1.getName()).willReturn("디폴트 카테고리"); + given(defaultCategory2.getName()).willReturn("디폴트 카테고리2"); + given(defaultCategory3.getName()).willReturn("디폴트 카테고리3"); - ConsumptionGoal topConsumptionGoal4 = ConsumptionGoal.builder() - .goalAmount(8000L) - .consumeAmount(3000L) - .user(user) - .category(defaultCategory4) - .goalMonth(goalMonthRandomDay) - .build(); + CategoryConsumptionCountDto topConsumption1 = new CategoryConsumptionCountDto(defaultCategory1.getId(), 30L); + CategoryConsumptionCountDto topConsumption2 = new CategoryConsumptionCountDto(defaultCategory2.getId(), 25L); + CategoryConsumptionCountDto topConsumption3 = new CategoryConsumptionCountDto(defaultCategory3.getId(), 20L); + + int peerAgeStart = 23; + int peerAgeEnd = 25; + String peerGender = "MALE"; given(userRepository.findById(user.getId())).willReturn(Optional.of(user)); - given(consumptionGoalRepository.findTopCategoriesAndGoalAmountLimit(4, 23, 25, Gender.MALE, - currentMonth)).willReturn( - List.of(topConsumptionGoal1, topConsumptionGoal2, topConsumptionGoal3, topConsumptionGoal4)); + given(consumptionGoalRepository.findTopCategoriesByConsumptionCount(peerAgeStart, peerAgeEnd, + Gender.valueOf(peerGender), currentMonth)) + .willReturn(List.of(topConsumption1, topConsumption2, topConsumption3)); + + given(categoryRepository.findById(defaultCategory1.getId())).willReturn(Optional.of(defaultCategory1)); + given(categoryRepository.findById(defaultCategory2.getId())).willReturn(Optional.of(defaultCategory2)); + given(categoryRepository.findById(defaultCategory3.getId())).willReturn(Optional.of(defaultCategory3)); // when - List result = consumptionGoalService.getTopGoalCategoriesLimit(4, user.getId(), 0, - 0, - "none"); + List result = consumptionGoalService.getTopConsumptionCategories( + user.getId(), peerAgeStart, peerAgeEnd, peerGender); // then - assertThat(result).hasSize(4); - assertThat(result.get(0).getCategoryName()).isEqualTo(defaultCategory.getName()); - assertThat(result.get(0).getGoalAmount()).isEqualTo(topConsumptionGoal1.getGoalAmount()); + assertThat(result).hasSize(3); + + assertThat(result.get(0).getCategoryName()).isEqualTo(defaultCategory1.getName()); + assertThat(result.get(0).getConsumptionCount()).isEqualTo(topConsumption1.getConsumptionCount()); + assertThat(result.get(1).getCategoryName()).isEqualTo(defaultCategory2.getName()); - assertThat(result.get(1).getGoalAmount()).isEqualTo(topConsumptionGoal2.getGoalAmount()); + assertThat(result.get(1).getConsumptionCount()).isEqualTo(topConsumption2.getConsumptionCount()); + assertThat(result.get(2).getCategoryName()).isEqualTo(defaultCategory3.getName()); - assertThat(result.get(2).getGoalAmount()).isEqualTo(topConsumptionGoal3.getGoalAmount()); - assertThat(result.get(3).getCategoryName()).isEqualTo(defaultCategory4.getName()); - assertThat(result.get(3).getGoalAmount()).isEqualTo(topConsumptionGoal4.getGoalAmount()); + assertThat(result.get(2).getConsumptionCount()).isEqualTo(topConsumption3.getConsumptionCount()); } @Test - @DisplayName("getTopConsumption : 또래들이 가장 많이 소비한 카테고리 top3 조회 성공") - void getTopConsumptionCategories_Success() { + @DisplayName("getAllConsumptionGoalCategories : 또래들이 세운 가장 큰 목표 카테고리 전체조회 성공") + void getAllConsumptionGoalCategories_Success() { // given - Category defaultCategory = Mockito.spy(Category.builder().name("디폴트 카테고리").user(null).isDefault(true).build()); - Category defaultCategory2 = Mockito.spy( - Category.builder().name("디폴트 카테고리2").user(null).isDefault(true).build()); - Category defaultCategory3 = Mockito.spy( - Category.builder().name("디폴트 카테고리3").user(null).isDefault(true).build()); + Category defaultCategory1 = new Category(); + Category defaultCategory2 = new Category(); + + defaultCategory1.setId(1L); + defaultCategory1.setName("디폴트 카테고리1"); + defaultCategory1.setIsDefault(true); + + defaultCategory2.setId(2L); + defaultCategory2.setName("디폴트 카테고리2"); + defaultCategory2.setIsDefault(true); + + List categoryAvgList = List.of( + new AvgConsumptionGoalDto(1L, 3000L), + new AvgConsumptionGoalDto(2L, 4000L) + ); + + List myConsumptionAmountList = List.of( + new MyConsumptionGoalDto(1L, 5000L), + new MyConsumptionGoalDto(2L, 2000L) + ); + + List defaultCategories = List.of(defaultCategory1, defaultCategory2); + + given(categoryRepository.findAllByIsDefaultTrue()).willReturn(defaultCategories); + given(consumptionGoalRepository.findAvgGoalAmountByCategory( + anyInt(), anyInt(), any(), any())).willReturn(categoryAvgList); + given(consumptionGoalRepository.findAllGoalAmountByUserId(user.getId())) + .willReturn(myConsumptionAmountList); + given(userRepository.findById(user.getId())).willReturn(Optional.of(user)); - ConsumptionGoal topConsumptionGoal1 = ConsumptionGoal.builder() - .goalAmount(5000L) - .consumeAmount(3000L) - .user(user) - .category(defaultCategory) - .goalMonth(goalMonthRandomDay) - .build(); + // when + List result = consumptionGoalService.getAllConsumptionGoalCategories( + user.getId(), 23, 25, "MALE"); - ConsumptionGoal topConsumptionGoal2 = ConsumptionGoal.builder() - .goalAmount(6000L) - .consumeAmount(3000L) - .user(user) - .category(defaultCategory2) - .goalMonth(goalMonthRandomDay) - .build(); + // then + assertThat(result).isNotNull(); + assertThat(result).hasSize(2); - ConsumptionGoal topConsumptionGoal3 = ConsumptionGoal.builder() - .goalAmount(7000L) - .consumeAmount(3000L) - .user(user) - .category(defaultCategory3) - .goalMonth(goalMonthRandomDay) - .build(); + AllConsumptionCategoryResponseDto firstCategory = result.get(0); + assertThat(firstCategory.getCategoryName()).isEqualTo("디폴트 카테고리1"); + assertThat(firstCategory.getAvgAmount()).isEqualTo(3000L); + assertThat(firstCategory.getAmountDifference()).isEqualTo(2000L); + + AllConsumptionCategoryResponseDto secondCategory = result.get(1); + assertThat(secondCategory.getCategoryName()).isEqualTo("디폴트 카테고리2"); + assertThat(secondCategory.getAvgAmount()).isEqualTo(4000L); + assertThat(secondCategory.getAmountDifference()).isEqualTo(-2000L); + } + @Test + @DisplayName("getAllConsumptionCategories : 또래들이 가장 많이 소비한 카테고리 전체조회 성공") + void getAllConsumptionCategories_Success() { + // given + Category defaultCategory1 = new Category(); + defaultCategory1.setId(1L); + defaultCategory1.setName("디폴트 카테고리1"); + defaultCategory1.setIsDefault(true); + + Category defaultCategory2 = new Category(); + defaultCategory2.setId(2L); + defaultCategory2.setName("디폴트 카테고리2"); + defaultCategory2.setIsDefault(true); + + List categoryAvgList = List.of( + new AvgConsumptionGoalDto(1L, 3000L), + new AvgConsumptionGoalDto(2L, 4000L) + ); + + List myConsumptionAmountList = List.of( + new MyConsumptionGoalDto(1L, 5000L), + new MyConsumptionGoalDto(2L, 2000L) + ); + + List defaultCategories = List.of(defaultCategory1, defaultCategory2); + + given(categoryRepository.findAllByIsDefaultTrue()).willReturn(defaultCategories); + given(consumptionGoalRepository.findAvgConsumptionAmountByCategory( + anyInt(), anyInt(), any(), any())).willReturn(categoryAvgList); given(userRepository.findById(user.getId())).willReturn(Optional.of(user)); - given(consumptionGoalRepository.findTopConsumptionAndConsumeAmountLimit(3, 23, 25, Gender.MALE, - currentMonth)).willReturn( - List.of(topConsumptionGoal1, topConsumptionGoal2, topConsumptionGoal3)); // when - List result = consumptionGoalService.getTopConsumptionsLimit(3, user.getId(), 23, 25, "MALE"); + List result = consumptionGoalService.getAllConsumptionCategories( + user.getId(), 23, 25, "MALE"); // then - assertThat(result).hasSize(3); - assertThat(result.get(0).getCategoryName()).isEqualTo(defaultCategory.getName()); - assertThat(result.get(0).getConsumeAmount()).isEqualTo(topConsumptionGoal1.getConsumeAmount()); - assertThat(result.get(1).getCategoryName()).isEqualTo(defaultCategory2.getName()); - assertThat(result.get(1).getConsumeAmount()).isEqualTo(topConsumptionGoal2.getConsumeAmount()); - assertThat(result.get(2).getCategoryName()).isEqualTo(defaultCategory3.getName()); - assertThat(result.get(2).getConsumeAmount()).isEqualTo(topConsumptionGoal3.getConsumeAmount()); + assertThat(result).isNotNull(); + assertThat(result).hasSize(2); + + AllConsumptionCategoryResponseDto firstCategory = result.get(0); + assertThat(firstCategory.getCategoryName()).isEqualTo("디폴트 카테고리1"); + assertThat(firstCategory.getAvgAmount()).isEqualTo(3000L); + assertThat(firstCategory.getAmountDifference()).isEqualTo(-3000); + + AllConsumptionCategoryResponseDto secondCategory = result.get(1); + assertThat(secondCategory.getCategoryName()).isEqualTo("디폴트 카테고리2"); + assertThat(secondCategory.getAvgAmount()).isEqualTo(4000L); + assertThat(secondCategory.getAmountDifference()).isEqualTo(-4000L); } @Test