From f3fecd8ff224aa2be2037ee9b6f3c401ce17f79f Mon Sep 17 00:00:00 2001 From: Hyeonsu Lee <127578418+20HyeonsuLee@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:21:27 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feature:=20=EB=AA=A8=EB=93=A0=20=EC=83=81?= =?UTF-8?q?=EC=A0=90=20=EC=A1=B0=ED=9A=8C=20API=EC=97=90=20=ED=98=9C?= =?UTF-8?q?=ED=83=9D=20=EC=83=81=EC=84=B8=20=ED=95=84=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#1121)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 모든 상점 조회시 혜택 필드 추가 * refactor: 리뷰 반영 --------- Co-authored-by: 송선권 Co-authored-by: Hwang HyeonSik <142300831+Choon0414@users.noreply.github.com> Co-authored-by: 배진호 Co-authored-by: 김성재 <103095432+seongjae6751@users.noreply.github.com> Co-authored-by: 신관규 Co-authored-by: HyeonsuLee --- .../benefit/model/BenefitCategoryMap.java | 9 ++- .../BenefitCategoryMapRepository.java | 8 +++ .../dto/shop/response/ShopsResponseV2.java | 17 +++-- .../koin/domain/shop/service/ShopService.java | 43 ++++++++---- .../V104__add_shop_benefit_detail.sql | 2 + .../koin/acceptance/ShopApiTest.java | 69 +++++++++++++++++++ .../fixture/BenefitCategoryMapFixture.java | 8 +++ 7 files changed, 138 insertions(+), 18 deletions(-) create mode 100644 src/main/resources/db/migration/V104__add_shop_benefit_detail.sql diff --git a/src/main/java/in/koreatech/koin/domain/benefit/model/BenefitCategoryMap.java b/src/main/java/in/koreatech/koin/domain/benefit/model/BenefitCategoryMap.java index 5da5479df..f416584cd 100644 --- a/src/main/java/in/koreatech/koin/domain/benefit/model/BenefitCategoryMap.java +++ b/src/main/java/in/koreatech/koin/domain/benefit/model/BenefitCategoryMap.java @@ -5,6 +5,7 @@ import in.koreatech.koin.domain.shop.model.shop.Shop; import in.koreatech.koin.global.domain.BaseEntity; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -12,6 +13,7 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; +import jakarta.validation.constraints.Size; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -34,9 +36,14 @@ public class BenefitCategoryMap extends BaseEntity { @JoinColumn(name = "benefit_id", referencedColumnName = "id", nullable = false) private BenefitCategory benefitCategory; + @Size(min = 2, max = 20) + @Column(name = "detail") + private String detail; + @Builder - public BenefitCategoryMap(Shop shop, BenefitCategory benefitCategory) { + public BenefitCategoryMap(Shop shop, BenefitCategory benefitCategory, String detail) { this.shop = shop; this.benefitCategory = benefitCategory; + this.detail = detail; } } diff --git a/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java b/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java index a29f48c36..cb2590edb 100644 --- a/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java +++ b/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java @@ -2,6 +2,7 @@ import java.util.List; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import in.koreatech.koin.domain.benefit.model.BenefitCategoryMap; @@ -10,5 +11,12 @@ public interface BenefitCategoryMapRepository extends Repository findAllByBenefitCategoryId(Integer benefitCategoryId); + @Query(""" + SELECT bcm FROM BenefitCategoryMap bcm + JOIN FETCH bcm.shop s + JOIN FETCH bcm.benefitCategory bc + """) + List findAllWithFetchJoin(); + BenefitCategoryMap save(BenefitCategoryMap benefitCategoryMap); } diff --git a/src/main/java/in/koreatech/koin/domain/shop/dto/shop/response/ShopsResponseV2.java b/src/main/java/in/koreatech/koin/domain/shop/dto/shop/response/ShopsResponseV2.java index a391a3204..e0700f1ff 100644 --- a/src/main/java/in/koreatech/koin/domain/shop/dto/shop/response/ShopsResponseV2.java +++ b/src/main/java/in/koreatech/koin/domain/shop/dto/shop/response/ShopsResponseV2.java @@ -42,7 +42,8 @@ public static ShopsResponseV2 from( ShopsSortCriteria sortBy, List shopsFilterCriterias, LocalDateTime now, - String query + String query, + Map> benefitDetail ) { List innerShopResponses = shops.stream() .filter(queryPredicate(query)) @@ -53,7 +54,8 @@ public static ShopsResponseV2 from( shopInfo.durationEvent(), it.isOpen(now), shopInfo.averageRate(), - shopInfo.reviewCount() + shopInfo.reviewCount(), + benefitDetail.getOrDefault(it.id(), List.of()) ); }) .filter(ShopsFilterCriteria.createCombinedFilter(shopsFilterCriterias)) @@ -101,7 +103,10 @@ public record InnerShopResponse( double averageRate, @Schema(example = "10", description = "리뷰 개수", requiredMode = REQUIRED) - long reviewCount + long reviewCount, + + @Schema(example = "['배달비 무료', '콜라 서비스']", description = "혜택 설명", requiredMode = NOT_REQUIRED) + List benefitDetails ) { @JsonNaming(value = SnakeCaseStrategy.class) @@ -138,7 +143,8 @@ public static InnerShopResponse from( Boolean isEvent, Boolean isOpen, Double averageRate, - Long reviewCount + Long reviewCount, + List benefitDetails ) { return new InnerShopResponse( shop.shopCategories().stream().map(ShopCategoryCache::id).toList(), @@ -159,7 +165,8 @@ public static InnerShopResponse from( isEvent, isOpen, averageRate, - reviewCount + reviewCount, + benefitDetails ); } diff --git a/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java b/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java index edd973b1a..d73512fbb 100644 --- a/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java +++ b/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java @@ -2,6 +2,8 @@ import static in.koreatech.koin.global.domain.notification.model.NotificationSubscribeType.REVIEW_PROMPT; +import in.koreatech.koin.domain.benefit.model.BenefitCategoryMap; +import in.koreatech.koin.domain.benefit.repository.BenefitCategoryMapRepository; import in.koreatech.koin.domain.shop.cache.ShopsCacheService; import in.koreatech.koin.domain.shop.cache.dto.ShopsCache; import in.koreatech.koin.domain.shop.dto.shop.ShopsFilterCriteria; @@ -24,6 +26,8 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.RequiredArgsConstructor; @@ -43,6 +47,7 @@ public class ShopService { private final ShopCustomRepository shopCustomRepository; private final NotificationSubscribeRepository notificationSubscribeRepository; private final ShopReviewNotificationRedisRepository shopReviewNotificationRedisRepository; + private final BenefitCategoryMapRepository benefitCategoryMapRepository; public ShopResponse getShop(Integer shopId) { Shop shop = shopRepository.getById(shopId); @@ -63,9 +68,9 @@ public ShopCategoriesResponse getShopsCategories() { } public ShopsResponseV2 getShopsV2( - ShopsSortCriteria sortBy, - List filterCriteria, - String query + ShopsSortCriteria sortBy, + List filterCriteria, + String query ) { if (filterCriteria.contains(null)) { throw KoinIllegalArgumentException.withDetail("유효하지 않은 필터입니다."); @@ -73,13 +78,27 @@ public ShopsResponseV2 getShopsV2( ShopsCache shopCaches = shopsCache.findAllShopCache(); LocalDateTime now = LocalDateTime.now(clock); Map shopInfoMap = shopCustomRepository.findAllShopInfo(now); + List benefitCategorys = benefitCategoryMapRepository.findAllWithFetchJoin(); + Map> benefitDetailMap = new HashMap<>(benefitCategorys.size()); + benefitCategorys.forEach(benefitCategory -> { + int shopId = benefitCategory.getShop().getId(); + String benefitDetail = benefitCategory.getDetail(); + if (benefitDetailMap.containsKey(shopId)) { + benefitDetailMap.get(shopId).add(benefitDetail); + } else { + List details = new ArrayList<>(); + details.add(benefitDetail); + benefitDetailMap.put(shopId, details); + } + }); return ShopsResponseV2.from( - shopCaches.shopCaches(), - shopInfoMap, - sortBy, - filterCriteria, - now, - query + shopCaches.shopCaches(), + shopInfoMap, + sortBy, + filterCriteria, + now, + query, + benefitDetailMap ); } @@ -88,9 +107,9 @@ public void publishCallNotification(Integer shopId, Integer studentId) { if (isSubscribeReviewNotification(studentId)) { ShopReviewNotification shopReviewNotification = ShopReviewNotification.builder() - .shopId(shopId) - .studentId(studentId) - .build(); + .shopId(shopId) + .studentId(studentId) + .build(); double score = LocalDateTime.now(clock).plusHours(1).toEpochSecond(ZoneOffset.UTC); shopReviewNotificationRedisRepository.save(shopReviewNotification, score); diff --git a/src/main/resources/db/migration/V104__add_shop_benefit_detail.sql b/src/main/resources/db/migration/V104__add_shop_benefit_detail.sql new file mode 100644 index 000000000..c25f2cb76 --- /dev/null +++ b/src/main/resources/db/migration/V104__add_shop_benefit_detail.sql @@ -0,0 +1,2 @@ +ALTER TABLE `shop_benefit_category_map` + ADD COLUMN `detail` VARCHAR(20); diff --git a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java index 60c6a7a0a..90c103288 100644 --- a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java @@ -7,6 +7,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import in.koreatech.koin.domain.benefit.model.BenefitCategory; +import in.koreatech.koin.fixture.BenefitCategoryFixture; +import in.koreatech.koin.fixture.BenefitCategoryMapFixture; import java.time.LocalDate; import org.junit.jupiter.api.BeforeAll; @@ -40,6 +43,12 @@ @TestInstance(TestInstance.Lifecycle.PER_CLASS) class ShopApiTest extends AcceptanceTest { + @Autowired + private BenefitCategoryFixture benefitCategoryFixture; + + @Autowired + private BenefitCategoryMapFixture benefitCategoryMapFixture; + @Autowired private UserFixture userFixture; @@ -1897,4 +1906,64 @@ void setUp() { ) .andExpect(status().isOk()); } + + @Test + void 리뷰를_조회하면_혜택_정보가_조회된다() throws Exception { + Shop 영업중인_티바 = shopFixture.영업중인_티바(owner); + shopReviewFixture.리뷰_4점(익명_학생, 영업중인_티바); + + shopReviewFixture.리뷰_4점(익명_학생, 마슬랜); + shopReviewFixture.리뷰_4점(익명_학생, 마슬랜); + // 2024-01-15 12:00 월요일 기준 + boolean 마슬랜_영업여부 = true; + boolean 티바_영업여부 = true; + + BenefitCategory 최소주문금액_무료 = benefitCategoryFixture.최소주문금액_무료(); + BenefitCategory 서비스_증정 = benefitCategoryFixture.서비스_증정(); + benefitCategoryMapFixture.설명이_포함된_혜택_추가(영업중인_티바, 최소주문금액_무료, "무료"); + benefitCategoryMapFixture.설명이_포함된_혜택_추가(영업중인_티바, 서비스_증정, "콜라"); + mockMvc.perform( + get("/v2/shops") + .queryParam("sorter", "COUNT_DESC") + ) + .andExpect(status().isOk()) + .andExpect(content().json(String.format(""" + { + "count": 2, + "shops": [ + { + "category_ids": [ + \s + ], + "delivery": true, + "id": 1, + "name": "마슬랜 치킨", + "pay_bank": true, + "pay_card": true, + "phone": "010-7574-1212", + "is_event": false, + "is_open": %s, + "average_rate": 4.0, + "review_count": 2, + "benefit_details": [] + },{ + "category_ids": [ + \s + ], + "delivery": true, + "id": 2, + "name": "티바", + "pay_bank": true, + "pay_card": true, + "phone": "010-7788-9900", + "is_event": false, + "is_open": %s, + "average_rate": 4.0, + "review_count": 1, + "benefit_details": ["무료", "콜라"] + } + ] + } + """, 티바_영업여부, 마슬랜_영업여부))); + } } diff --git a/src/test/java/in/koreatech/koin/fixture/BenefitCategoryMapFixture.java b/src/test/java/in/koreatech/koin/fixture/BenefitCategoryMapFixture.java index 8eca67285..abf8583c4 100644 --- a/src/test/java/in/koreatech/koin/fixture/BenefitCategoryMapFixture.java +++ b/src/test/java/in/koreatech/koin/fixture/BenefitCategoryMapFixture.java @@ -25,4 +25,12 @@ public BenefitCategoryMapFixture( .benefitCategory(benefitCategory) .build()); } + + public BenefitCategoryMap 설명이_포함된_혜택_추가(Shop shop, BenefitCategory benefitCategory, String detail) { + return benefitCategoryMapRepository.save(BenefitCategoryMap.builder() + .shop(shop) + .benefitCategory(benefitCategory) + .detail(detail) + .build()); + } } From d874940e77aef4831c9862d0583f16baa91aff69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=B0=EC=A7=84=ED=98=B8?= Date: Sat, 7 Dec 2024 20:37:49 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=EC=83=81=EC=A0=90=20=ED=98=9C?= =?UTF-8?q?=ED=83=9D=20=EC=83=81=EC=84=B8=EB=B3=B4=EA=B8=B0=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80=20(#1123)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 혜택 카테고리별 상점 조회시 혜택 상세보기 추가 * test: 테스트 필드 추가 * fix: 피드백 반영 --- .../benefit/controller/AdminBenefitApi.java | 4 ++-- .../controller/AdminBenefitController.java | 6 +++--- ....java => AdminBenefitCategoriesResponse.java} | 6 +++--- .../benefit/service/AdminBenefitService.java | 6 +++--- .../domain/benefit/dto/BenefitShopsResponse.java | 12 +++++++++--- .../repository/BenefitCategoryMapRepository.java | 2 +- .../benefit/service/ShopBenefitService.java | 16 +++++++++++----- .../koin/acceptance/BenefitApiTest.java | 5 +++-- 8 files changed, 35 insertions(+), 22 deletions(-) rename src/main/java/in/koreatech/koin/admin/benefit/dto/{AdminBenefitCategoryResponse.java => AdminBenefitCategoriesResponse.java} (89%) diff --git a/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitApi.java b/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitApi.java index 510a696eb..9b0ea821f 100644 --- a/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitApi.java +++ b/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitApi.java @@ -12,7 +12,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import in.koreatech.koin.admin.benefit.dto.AdminBenefitCategoryResponse; +import in.koreatech.koin.admin.benefit.dto.AdminBenefitCategoriesResponse; import in.koreatech.koin.admin.benefit.dto.AdminBenefitShopsResponse; import in.koreatech.koin.admin.benefit.dto.AdminCreateBenefitCategoryRequest; import in.koreatech.koin.admin.benefit.dto.AdminCreateBenefitCategoryResponse; @@ -44,7 +44,7 @@ public interface AdminBenefitApi { ) @Operation(summary = "상점 혜택 카테고리를 모두 조회한다.") @GetMapping("/categories") - ResponseEntity getBenefitCategories( + ResponseEntity getBenefitCategories( @Auth(permit = {ADMIN}) Integer adminId ); diff --git a/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitController.java b/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitController.java index d5fb072d4..544180fbc 100644 --- a/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitController.java +++ b/src/main/java/in/koreatech/koin/admin/benefit/controller/AdminBenefitController.java @@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import in.koreatech.koin.admin.benefit.dto.AdminBenefitCategoryResponse; +import in.koreatech.koin.admin.benefit.dto.AdminBenefitCategoriesResponse; import in.koreatech.koin.admin.benefit.dto.AdminBenefitShopsResponse; import in.koreatech.koin.admin.benefit.dto.AdminCreateBenefitCategoryRequest; import in.koreatech.koin.admin.benefit.dto.AdminCreateBenefitCategoryResponse; @@ -36,10 +36,10 @@ public class AdminBenefitController implements AdminBenefitApi { private final AdminBenefitService adminBenefitService; @GetMapping("/categories") - public ResponseEntity getBenefitCategories( + public ResponseEntity getBenefitCategories( @Auth(permit = {ADMIN}) Integer adminId ) { - AdminBenefitCategoryResponse response = adminBenefitService.getBenefitCategories(); + AdminBenefitCategoriesResponse response = adminBenefitService.getBenefitCategories(); return ResponseEntity.ok(response); } diff --git a/src/main/java/in/koreatech/koin/admin/benefit/dto/AdminBenefitCategoryResponse.java b/src/main/java/in/koreatech/koin/admin/benefit/dto/AdminBenefitCategoriesResponse.java similarity index 89% rename from src/main/java/in/koreatech/koin/admin/benefit/dto/AdminBenefitCategoryResponse.java rename to src/main/java/in/koreatech/koin/admin/benefit/dto/AdminBenefitCategoriesResponse.java index 379d3019a..ce74fc882 100644 --- a/src/main/java/in/koreatech/koin/admin/benefit/dto/AdminBenefitCategoryResponse.java +++ b/src/main/java/in/koreatech/koin/admin/benefit/dto/AdminBenefitCategoriesResponse.java @@ -9,13 +9,13 @@ import io.swagger.v3.oas.annotations.media.Schema; @JsonNaming(SnakeCaseStrategy.class) -public record AdminBenefitCategoryResponse( +public record AdminBenefitCategoriesResponse( @Schema(description = "혜택 카테고리 리스트") List benefits ) { - public static AdminBenefitCategoryResponse from(List benefitCategories) { - return new AdminBenefitCategoryResponse( + public static AdminBenefitCategoriesResponse from(List benefitCategories) { + return new AdminBenefitCategoriesResponse( benefitCategories.stream().map(InnerBenefitResponse::from).toList() ); } diff --git a/src/main/java/in/koreatech/koin/admin/benefit/service/AdminBenefitService.java b/src/main/java/in/koreatech/koin/admin/benefit/service/AdminBenefitService.java index b00c2e819..7b349578e 100644 --- a/src/main/java/in/koreatech/koin/admin/benefit/service/AdminBenefitService.java +++ b/src/main/java/in/koreatech/koin/admin/benefit/service/AdminBenefitService.java @@ -7,7 +7,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import in.koreatech.koin.admin.benefit.dto.AdminBenefitCategoryResponse; +import in.koreatech.koin.admin.benefit.dto.AdminBenefitCategoriesResponse; import in.koreatech.koin.admin.benefit.dto.AdminBenefitShopsResponse; import in.koreatech.koin.admin.benefit.dto.AdminCreateBenefitCategoryRequest; import in.koreatech.koin.admin.benefit.dto.AdminCreateBenefitCategoryResponse; @@ -36,9 +36,9 @@ public class AdminBenefitService { private final AdminBenefitCategoryMapRepository adminBenefitCategoryMapRepository; private final AdminShopRepository adminShopRepository; - public AdminBenefitCategoryResponse getBenefitCategories() { + public AdminBenefitCategoriesResponse getBenefitCategories() { List categories = adminBenefitCategoryRepository.findAllByOrderByTitleAsc(); - return AdminBenefitCategoryResponse.from(categories); + return AdminBenefitCategoriesResponse.from(categories); } @Transactional diff --git a/src/main/java/in/koreatech/koin/domain/benefit/dto/BenefitShopsResponse.java b/src/main/java/in/koreatech/koin/domain/benefit/dto/BenefitShopsResponse.java index 477fdc100..b33d49f50 100644 --- a/src/main/java/in/koreatech/koin/domain/benefit/dto/BenefitShopsResponse.java +++ b/src/main/java/in/koreatech/koin/domain/benefit/dto/BenefitShopsResponse.java @@ -7,6 +7,7 @@ import java.time.LocalTime; import java.util.Comparator; import java.util.List; +import java.util.Map; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonNaming; @@ -67,7 +68,10 @@ public record InnerShopResponse( double averageRate, @Schema(example = "10", description = "리뷰 개수", requiredMode = REQUIRED) - long reviewCount + long reviewCount, + + @Schema(example = "콜라 서비스", description = "혜택 설명", requiredMode = NOT_REQUIRED) + String benefitDetail ) { public static Comparator getComparator() { @@ -80,7 +84,8 @@ public static Comparator getComparator() { public static InnerShopResponse from( Shop shop, boolean isEvent, - boolean isOpen + boolean isOpen, + String benefitDetail ) { return new InnerShopResponse( shop.getShopCategories().stream().map(shopCategoryMap -> @@ -102,7 +107,8 @@ public static InnerShopResponse from( .orElse(0.0) * 10) / 10.0, shop.getReviews().stream() .filter(review -> !review.isDeleted()) - .count() + .count(), + benefitDetail ); } diff --git a/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java b/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java index cb2590edb..1555fc173 100644 --- a/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java +++ b/src/main/java/in/koreatech/koin/domain/benefit/repository/BenefitCategoryMapRepository.java @@ -9,7 +9,7 @@ public interface BenefitCategoryMapRepository extends Repository { - List findAllByBenefitCategoryId(Integer benefitCategoryId); + List findByBenefitCategoryId(Integer benefitCategoryId); @Query(""" SELECT bcm FROM BenefitCategoryMap bcm diff --git a/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java b/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java index a309885fc..9d41fb04f 100644 --- a/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java +++ b/src/main/java/in/koreatech/koin/domain/benefit/service/ShopBenefitService.java @@ -35,18 +35,24 @@ public BenefitCategoryResponse getBenefitCategories() { } public BenefitShopsResponse getBenefitShops(Integer benefitId) { - List benefitCategoryMaps = benefitCategoryMapRepository - .findAllByBenefitCategoryId(benefitId); + List benefitCategoryMaps = benefitCategoryMapRepository.findByBenefitCategoryId(benefitId); LocalDateTime now = LocalDateTime.now(clock); + List innerShopResponses = benefitCategoryMaps.stream() .map(benefitCategoryMap -> { Shop shop = benefitCategoryMap.getShop(); + String benefitDetail = benefitCategoryMap.getDetail(); boolean isDurationEvent = eventArticleRepository.isDurationEvent(shop.getId(), now.toLocalDate()); - return InnerShopResponse.from(shop, isDurationEvent, shop.isOpen(now)); + return InnerShopResponse.from( + shop, + isDurationEvent, + shop.isOpen(now), + benefitDetail + ); }) .sorted(InnerShopResponse.getComparator()) .toList(); - BenefitShopsResponse shopsResponse = BenefitShopsResponse.from(innerShopResponses); - return shopsResponse; + + return BenefitShopsResponse.from(innerShopResponses); } } diff --git a/src/test/java/in/koreatech/koin/acceptance/BenefitApiTest.java b/src/test/java/in/koreatech/koin/acceptance/BenefitApiTest.java index 8de1c7301..836d56fc1 100644 --- a/src/test/java/in/koreatech/koin/acceptance/BenefitApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/BenefitApiTest.java @@ -95,7 +95,7 @@ void setup() { 성빈_학생 = userFixture.성빈_학생(); - benefitCategoryMapFixture.혜택_추가(김밥천국, 배달비_무료); + benefitCategoryMapFixture.설명이_포함된_혜택_추가(김밥천국, 배달비_무료, "무료"); benefitCategoryMapFixture.혜택_추가(마슬랜, 배달비_무료); benefitCategoryMapFixture.혜택_추가(영업중인_티바, 배달비_무료); benefitCategoryMapFixture.혜택_추가(영업중이_아닌_신전_떡볶이, 배달비_무료); @@ -183,7 +183,8 @@ void setup() { "is_event": false, "is_open": true, "average_rate": 5.0, - "review_count": 1 + "review_count": 1, + "benefit_detail": "무료" }, { "category_ids": [],