diff --git a/src/main/java/com/coolpeace/domain/coupon/controller/CouponController.java b/src/main/java/com/coolpeace/domain/coupon/controller/CouponController.java index 142d6041..ca4d6547 100644 --- a/src/main/java/com/coolpeace/domain/coupon/controller/CouponController.java +++ b/src/main/java/com/coolpeace/domain/coupon/controller/CouponController.java @@ -3,18 +3,12 @@ import com.coolpeace.domain.coupon.dto.request.CouponExposeRequest; import com.coolpeace.domain.coupon.dto.request.CouponRegisterRequest; import com.coolpeace.domain.coupon.dto.request.CouponUpdateRequest; -import com.coolpeace.domain.coupon.dto.request.SearchCouponParams; -import com.coolpeace.domain.coupon.dto.response.CouponCategoryResponse; import com.coolpeace.domain.coupon.dto.response.CouponResponse; -import com.coolpeace.domain.coupon.dto.response.CouponSearchResponse; import com.coolpeace.domain.coupon.service.CouponService; import com.coolpeace.global.jwt.security.JwtPrincipal; import com.coolpeace.global.resolver.AuthJwtPrincipal; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -27,17 +21,12 @@ public class CouponController { private final CouponService couponService; - @GetMapping("/{accommodation_id}") - public ResponseEntity searchCoupons( - @PathVariable("accommodation_id") Long accommodationId, - @Valid SearchCouponParams searchCouponParams, - @PageableDefault Pageable pageable, - @AuthJwtPrincipal JwtPrincipal jwtPrincipal - ) { - Page couponResponses = couponService.searchCoupons( - Long.valueOf(jwtPrincipal.getMemberId()), accommodationId, searchCouponParams, pageable); - CouponCategoryResponse categoryResponse = couponService.getCouponCategories(); - return ResponseEntity.ok(CouponSearchResponse.from(couponResponses, categoryResponse)); + @GetMapping("/{coupon_number}") + public ResponseEntity getCouponByCouponNumber( + @PathVariable("coupon_number") String couponNumber, + @AuthJwtPrincipal JwtPrincipal jwtPrincipal) { + return ResponseEntity.ok(CouponResponse.from(couponService.getCouponByCouponNumber( + Long.valueOf(jwtPrincipal.getMemberId()), couponNumber))); } @GetMapping("/recent") diff --git a/src/main/java/com/coolpeace/domain/coupon/controller/CouponSearchController.java b/src/main/java/com/coolpeace/domain/coupon/controller/CouponSearchController.java new file mode 100644 index 00000000..6de5d5ad --- /dev/null +++ b/src/main/java/com/coolpeace/domain/coupon/controller/CouponSearchController.java @@ -0,0 +1,37 @@ +package com.coolpeace.domain.coupon.controller; + +import com.coolpeace.domain.coupon.dto.request.SearchCouponParams; +import com.coolpeace.domain.coupon.dto.response.CouponCategoryResponse; +import com.coolpeace.domain.coupon.dto.response.CouponResponse; +import com.coolpeace.domain.coupon.dto.response.CouponSearchResponse; +import com.coolpeace.domain.coupon.service.CouponService; +import com.coolpeace.global.jwt.security.JwtPrincipal; +import com.coolpeace.global.resolver.AuthJwtPrincipal; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +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.RestController; + +@RestController +@RequiredArgsConstructor +public class CouponSearchController { + private final CouponService couponService; + + @GetMapping("/v1/accommodations/{accommodation_id}/coupons") + public ResponseEntity searchCoupons( + @PathVariable("accommodation_id") Long accommodationId, + @Valid SearchCouponParams searchCouponParams, + @PageableDefault Pageable pageable, + @AuthJwtPrincipal JwtPrincipal jwtPrincipal + ) { + Page couponResponses = couponService.searchCoupons( + Long.valueOf(jwtPrincipal.getMemberId()), accommodationId, searchCouponParams, pageable); + CouponCategoryResponse categoryResponse = couponService.getCouponCategories(); + return ResponseEntity.ok(CouponSearchResponse.from(couponResponses, categoryResponse)); + } +} diff --git a/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponRegisterRequest.java b/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponRegisterRequest.java index c4caba3f..f7a96a86 100644 --- a/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponRegisterRequest.java +++ b/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponRegisterRequest.java @@ -1,6 +1,7 @@ package com.coolpeace.domain.coupon.dto.request; import com.coolpeace.domain.coupon.entity.type.CouponRoomType; +import com.coolpeace.domain.coupon.entity.type.CouponUseDaysType; import com.coolpeace.domain.coupon.entity.type.CustomerType; import com.coolpeace.domain.coupon.entity.type.DiscountType; import com.coolpeace.global.common.validator.ValidEnum; @@ -43,7 +44,8 @@ public record CouponRegisterRequest( // 쿠폰 사용 조건 Integer minimumReservationPrice, - List couponUseConditionDays, + @ValidEnum(enumClass = CouponUseDaysType.class, message = "올바르지 않은 사용 조건의 날짜 유형입니다.", required = false) + String couponUseConditionDays, // 노출 날짜 @NotNull(message = "노출 시작 날짜를 입력해야 합니다.") diff --git a/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponUpdateRequest.java b/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponUpdateRequest.java index cd8107e8..a4ccce5b 100644 --- a/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponUpdateRequest.java +++ b/src/main/java/com/coolpeace/domain/coupon/dto/request/CouponUpdateRequest.java @@ -1,6 +1,7 @@ package com.coolpeace.domain.coupon.dto.request; import com.coolpeace.domain.coupon.entity.type.CouponRoomType; +import com.coolpeace.domain.coupon.entity.type.CouponUseDaysType; import com.coolpeace.domain.coupon.entity.type.CustomerType; import com.coolpeace.domain.coupon.entity.type.DiscountType; import com.coolpeace.global.common.validator.ValidEnum; @@ -11,6 +12,7 @@ import java.util.List; public record CouponUpdateRequest( + String title, @NotNull(message = "숙박업체의 ID를 입력해야 합니다.") Long accommodationId, @ValidEnum(enumClass = CustomerType.class, message = "올바르지 않은 고객의 유형입니다.", required = false) @@ -23,7 +25,8 @@ public record CouponUpdateRequest( Boolean registerAllRoom, List registerRooms, Integer minimumReservationPrice, - List couponUseConditionDays, + @ValidEnum(enumClass = CouponUseDaysType.class, message = "올바르지 않은 사용 조건의 날짜 유형입니다.", required = false) + String couponUseConditionDays, @JsonFormat(pattern = "yyyy-MM-dd") LocalDate exposureStartDate, @JsonFormat(pattern = "yyyy-MM-dd") diff --git a/src/main/java/com/coolpeace/domain/coupon/dto/response/CouponResponse.java b/src/main/java/com/coolpeace/domain/coupon/dto/response/CouponResponse.java index c8afd5b7..38d218f4 100644 --- a/src/main/java/com/coolpeace/domain/coupon/dto/response/CouponResponse.java +++ b/src/main/java/com/coolpeace/domain/coupon/dto/response/CouponResponse.java @@ -2,7 +2,6 @@ import com.coolpeace.domain.accommodation.entity.Accommodation; import com.coolpeace.domain.coupon.entity.Coupon; -import com.coolpeace.global.common.DayOfWeekUtil; import java.time.LocalDate; import java.util.List; @@ -18,7 +17,7 @@ public record CouponResponse( String customerType, String couponRoomType, Integer minimumReservationPrice, - List couponUseConditionDays, + String couponUseConditionDays, LocalDate exposureStartDate, LocalDate exposureEndDate, Integer couponExpiration, @@ -40,7 +39,7 @@ public static CouponResponse from(Coupon coupon) { coupon.getCustomerType().getValue(), coupon.getCouponRoomType().getValue(), coupon.getMinimumReservationPrice(), - DayOfWeekUtil.fromDayOfWeeks(coupon.getCouponUseConditionDays()), + coupon.getCouponUseDays().getValue(), coupon.getExposureStartDate(), coupon.getExposureEndDate(), coupon.getCouponExpiration(), diff --git a/src/main/java/com/coolpeace/domain/coupon/entity/Coupon.java b/src/main/java/com/coolpeace/domain/coupon/entity/Coupon.java index eea802dd..dc0e3c8e 100644 --- a/src/main/java/com/coolpeace/domain/coupon/entity/Coupon.java +++ b/src/main/java/com/coolpeace/domain/coupon/entity/Coupon.java @@ -13,10 +13,7 @@ import java.time.DayOfWeek; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; @Getter @Entity @@ -52,7 +49,10 @@ public class Coupon extends BaseTimeEntity { private Integer minimumReservationPrice = 0; @Convert(converter = CouponUseConditionDaysTypeConverter.class) - private List couponUseConditionDays; + private final List couponUseConditionDays = Collections.emptyList(); + + @Enumerated(EnumType.STRING) + private CouponUseDaysType couponUseDays = CouponUseDaysType.ALL; @Column(nullable = false) private LocalDate exposureStartDate; @@ -86,7 +86,7 @@ public Coupon(String title, CustomerType customerType, CouponRoomType couponRoomType, Integer minimumReservationPrice, - List couponUseConditionDays, + CouponUseDaysType couponUseDays, LocalDate exposureStartDate, LocalDate exposureEndDate, Accommodation accommodation, @@ -98,7 +98,7 @@ public Coupon(String title, this.customerType = customerType; this.couponRoomType = couponRoomType; this.minimumReservationPrice = minimumReservationPrice; - this.couponUseConditionDays = couponUseConditionDays; + this.couponUseDays = couponUseDays; this.exposureStartDate = exposureStartDate; this.exposureEndDate = exposureEndDate; this.accommodation = accommodation; @@ -114,7 +114,7 @@ public static Coupon from( CustomerType customerType, CouponRoomType couponRoomType, Integer minimumReservationPrice, - List couponUseConditionDays, + CouponUseDaysType couponUseDays, LocalDate exposureStartDate, LocalDate exposureEndDate, Accommodation accommodation, @@ -128,7 +128,7 @@ public static Coupon from( customerType, couponRoomType, minimumReservationPrice, - couponUseConditionDays, + couponUseDays, exposureStartDate, exposureEndDate, accommodation, @@ -146,7 +146,7 @@ public String getCouponTitle() { public void generateCouponNumber(CouponIssuerType couponIssuerType, Long id) { this.couponNumber = - couponIssuerType.getValue() + String.format("%06d", Objects.requireNonNull(id)); + couponIssuerType.getValue() + String.format("%07d", Objects.requireNonNull(id)); } public void changeCouponStatus(CouponStatusType couponStatusType) { @@ -175,17 +175,18 @@ public void updateCoupon( CustomerType customerType, CouponRoomType couponRoomType, Integer minimumReservationPrice, - List couponUseConditionDays, + CouponUseDaysType couponUseDays, List rooms, LocalDate exposureStartDate, LocalDate exposureEndDate ) { + this.title = Optional.ofNullable(title).orElse(this.title); this.discountType = Optional.ofNullable(discountType).orElse(this.discountType); this.discountValue = Optional.ofNullable(discountValue).orElse(this.discountValue); this.customerType = Optional.ofNullable(customerType).orElse(this.customerType); this.couponRoomType = Optional.ofNullable(couponRoomType).orElse(this.couponRoomType); this.minimumReservationPrice = Optional.ofNullable(minimumReservationPrice).orElse(this.minimumReservationPrice); - this.couponUseConditionDays = Optional.ofNullable(couponUseConditionDays).orElse(this.couponUseConditionDays); + this.couponUseDays = Optional.ofNullable(couponUseDays).orElse(this.couponUseDays); if (rooms != null) { this.couponRooms = rooms.stream().map(room -> CouponRooms.from(this, room)).toList(); } diff --git a/src/main/java/com/coolpeace/domain/coupon/entity/type/CouponUseDaysType.java b/src/main/java/com/coolpeace/domain/coupon/entity/type/CouponUseDaysType.java new file mode 100644 index 00000000..7d9a2b91 --- /dev/null +++ b/src/main/java/com/coolpeace/domain/coupon/entity/type/CouponUseDaysType.java @@ -0,0 +1,22 @@ +package com.coolpeace.domain.coupon.entity.type; + +import com.coolpeace.global.common.ValuedEnum; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum CouponUseDaysType implements ValuedEnum { + MONDAY("월"), + TUESDAY("화"), + WEDNESDAY("수"), + THURSDAY("목"), + FRIDAY("금"), + SATURDAY("토"), + SUNDAY("일"), + WEEKDAY("평일"), + WEEKEND("주말"), + ALL("전체"); + + private final String value; +} diff --git a/src/main/java/com/coolpeace/domain/coupon/repository/CouponRepositoryImpl.java b/src/main/java/com/coolpeace/domain/coupon/repository/CouponRepositoryImpl.java index fb2a9893..ca59c777 100644 --- a/src/main/java/com/coolpeace/domain/coupon/repository/CouponRepositoryImpl.java +++ b/src/main/java/com/coolpeace/domain/coupon/repository/CouponRepositoryImpl.java @@ -54,6 +54,8 @@ public Page findAllCoupons(Long memberId, Long accommodationId, SearchCo .or(coupon.couponStatus.eq(CouponStatusType.DELETED)); case All -> coupon.couponStatus.ne(CouponStatusType.DELETED); }); + } else { + searchCouponPredicate.and(coupon.couponStatus.ne(CouponStatusType.DELETED)); } // 쿠폰 이름 diff --git a/src/main/java/com/coolpeace/domain/coupon/service/CouponService.java b/src/main/java/com/coolpeace/domain/coupon/service/CouponService.java index a47efb48..0154abc2 100644 --- a/src/main/java/com/coolpeace/domain/coupon/service/CouponService.java +++ b/src/main/java/com/coolpeace/domain/coupon/service/CouponService.java @@ -11,7 +11,10 @@ import com.coolpeace.domain.coupon.dto.response.CouponResponse; import com.coolpeace.domain.coupon.entity.Coupon; import com.coolpeace.domain.coupon.entity.type.*; -import com.coolpeace.domain.coupon.exception.*; +import com.coolpeace.domain.coupon.exception.CouponAccessDeniedException; +import com.coolpeace.domain.coupon.exception.CouponNotFoundException; +import com.coolpeace.domain.coupon.exception.CouponUpdateLimitExposureStateException; +import com.coolpeace.domain.coupon.exception.InvalidCouponStateOutsideExposureDateException; import com.coolpeace.domain.coupon.repository.CouponRepository; import com.coolpeace.domain.member.entity.Member; import com.coolpeace.domain.member.exception.MemberNotFoundException; @@ -20,7 +23,6 @@ import com.coolpeace.domain.room.exception.RegisterRoomsEmptyException; import com.coolpeace.domain.room.exception.RoomNotFoundException; import com.coolpeace.domain.room.repository.RoomRepository; -import com.coolpeace.global.common.DayOfWeekUtil; import com.coolpeace.global.common.ValuedEnum; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -31,7 +33,6 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; -import java.time.DayOfWeek; import java.time.LocalDate; import java.util.Collections; import java.util.List; @@ -69,6 +70,13 @@ public CouponCategoryResponse getCouponCategories() { return CouponCategoryResponse.from(all, exposureOn, exposureOff, expired); } + @Transactional(readOnly = true) + public Coupon getCouponByCouponNumber(Long memberId, String couponNumber) { + validateMemberHasCoupon(memberId, couponNumber); + return couponRepository.findByCouponNumber(couponNumber) + .orElseThrow(CouponNotFoundException::new); + } + @Transactional(readOnly = true) public List getRecentHistory(Long memberId) { return couponRepository.findRecentCouponByMemberId(memberId) @@ -101,8 +109,7 @@ public void register(Long memberId, CouponRegisterRequest couponRegisterRequest) ValuedEnum.of(CustomerType.class, couponRegisterRequest.customerType()), ValuedEnum.of(CouponRoomType.class, couponRegisterRequest.couponRoomType()), couponRegisterRequest.minimumReservationPrice(), - DayOfWeekUtil.fromDayOfWeekStrings(couponRegisterRequest.couponUseConditionDays()) - , + ValuedEnum.of(CouponUseDaysType.class, couponRegisterRequest.couponUseConditionDays()), couponRegisterRequest.exposureStartDate(), couponRegisterRequest.exposureEndDate(), accommodation, @@ -135,8 +142,8 @@ public void updateCoupon(Long memberId, String couponNumber, CouponUpdateRequest CouponRoomType couponRoomType = Optional.ofNullable(couponUpdateRequest.couponRoomType()) .map(str -> ValuedEnum.of(CouponRoomType.class, str)) .orElse(null); - List dayOfWeeks = Optional.ofNullable(couponUpdateRequest.couponUseConditionDays()) - .map(DayOfWeekUtil::fromDayOfWeekStrings) + CouponUseDaysType couponUseDays = Optional.ofNullable(couponUpdateRequest.couponUseConditionDays()) + .map(str -> ValuedEnum.of(CouponUseDaysType.class, str)) .orElse(null); storedCoupon.updateCoupon( @@ -145,7 +152,7 @@ public void updateCoupon(Long memberId, String couponNumber, CouponUpdateRequest customerType, couponRoomType, couponUpdateRequest.minimumReservationPrice(), - dayOfWeeks, + couponUseDays, rooms, couponUpdateRequest.exposureStartDate(), couponUpdateRequest.exposureEndDate() diff --git a/src/test/java/com/coolpeace/docs/coupon/CouponControllerTest.java b/src/test/java/com/coolpeace/docs/coupon/CouponControllerTest.java index bfd56549..db530cd0 100644 --- a/src/test/java/com/coolpeace/docs/coupon/CouponControllerTest.java +++ b/src/test/java/com/coolpeace/docs/coupon/CouponControllerTest.java @@ -22,7 +22,6 @@ import com.coolpeace.global.builder.AccommodationTestBuilder; import com.coolpeace.global.builder.CouponTestBuilder; import com.coolpeace.global.builder.RoomTestBuilder; -import com.coolpeace.global.common.DayOfWeekUtil; import com.coolpeace.global.common.RestDocsIntegrationTest; import com.coolpeace.global.util.CouponTestUtil; import com.coolpeace.global.util.MemberTestUtil; @@ -108,7 +107,7 @@ void registerCoupon_success() throws Exception { false, randomRoomNumbers, coupon.getMinimumReservationPrice(), - DayOfWeekUtil.fromDayOfWeeks(coupon.getCouponUseConditionDays()), + coupon.getCouponUseDays().getValue(), coupon.getExposureStartDate(), coupon.getExposureEndDate() ); @@ -138,7 +137,7 @@ void registerCoupon_success() throws Exception { fieldWithPath("register_all_room").type(JsonFieldType.BOOLEAN).description("객실 등록 여부"), fieldWithPath("register_rooms").type(JsonFieldType.ARRAY).description("등록될 객실의 리스트"), fieldWithPath("minimum_reservation_price").type(JsonFieldType.NUMBER).description("최소 예약 가격"), - fieldWithPath("coupon_use_condition_days").type(JsonFieldType.ARRAY).description("쿠폰 사용 가능 요일"), + fieldWithPath("coupon_use_condition_days").type(JsonFieldType.STRING).description("쿠폰 사용 가능 요일"), fieldWithPath("exposure_start_date").type(JsonFieldType.STRING).description("노출 시작 날짜"), fieldWithPath("exposure_end_date").type(JsonFieldType.STRING).description("노출 종료 날짜") ) @@ -167,7 +166,8 @@ void searchCoupon_success() throws Exception { // when MultiValueMap requestParams = createCouponSearchParams(); - ResultActions result = mockMvc.perform(get(URL_DOMAIN_PREFIX + "/{accommodation_id}", accommodation.getId()) + ResultActions result = mockMvc.perform(get("/v1/accommodations/{accommodation_id}/coupons", + accommodation.getId()) .header(AUTHORIZATION, BEARER_PREFIX + loginResponse.accessToken()) .queryParams(requestParams)); @@ -197,7 +197,7 @@ void searchCoupon_success() throws Exception { fieldWithPath("content[].customer_type").type(JsonFieldType.STRING).description("고객의 유형"), fieldWithPath("content[].coupon_room_type").type(JsonFieldType.STRING).description("객실의 유형"), fieldWithPath("content[].minimum_reservation_price").type(JsonFieldType.NUMBER).description("최소 예약 가격"), - fieldWithPath("content[].coupon_use_condition_days").type(JsonFieldType.ARRAY).description("쿠폰 사용 가능 요일"), + fieldWithPath("content[].coupon_use_condition_days").type(JsonFieldType.STRING).description("쿠폰 사용 가능 요일"), fieldWithPath("content[].exposure_start_date").type(JsonFieldType.STRING).description("노출 시작 날짜"), fieldWithPath("content[].exposure_end_date").type(JsonFieldType.STRING).description("노출 종료 날짜"), fieldWithPath("content[].coupon_expiration").type(JsonFieldType.NUMBER).description("쿠폰 만료 일자"), @@ -268,7 +268,7 @@ void getCouponRecentHistory_success() throws Exception { fieldWithPath("[].customer_type").type(JsonFieldType.STRING).description("고객의 유형"), fieldWithPath("[].coupon_room_type").type(JsonFieldType.STRING).description("객실의 유형"), fieldWithPath("[].minimum_reservation_price").type(JsonFieldType.NUMBER).description("최소 예약 가격"), - fieldWithPath("[].coupon_use_condition_days").type(JsonFieldType.ARRAY).description("쿠폰 사용 가능 요일"), + fieldWithPath("[].coupon_use_condition_days").type(JsonFieldType.STRING).description("쿠폰 사용 가능 요일"), fieldWithPath("[].exposure_start_date").type(JsonFieldType.STRING).description("노출 시작 날짜"), fieldWithPath("[].exposure_end_date").type(JsonFieldType.STRING).description("노출 종료 날짜"), fieldWithPath("[].coupon_expiration").type(JsonFieldType.NUMBER).description("쿠폰 만료 일자"), @@ -308,6 +308,54 @@ void getCouponRecentHistory_success_no_content() throws Exception { } } + @DisplayName("쿠폰 번호로 쿠폰 조회") + @Test + void getCouponByCouponNumber_success() throws Exception { + // given + MemberLoginResponse loginResponse = MemberTestUtil + .obtainAccessTokenByTestMember(mockMvc, objectMapper, registeredMember); + + List randomRooms = RoomTestUtil.getRandomRooms(rooms); + Coupon coupon = couponRepository.save(new CouponTestBuilder(accommodation, storedMember, randomRooms).build()); + coupon.generateCouponNumber(CouponIssuerType.OWNER, coupon.getId()); + + // when + ResultActions result = mockMvc.perform(get(URL_DOMAIN_PREFIX + "/{coupon_number}", coupon.getCouponNumber()) + .contentType(MediaType.APPLICATION_JSON) + .header(AUTHORIZATION, BEARER_PREFIX + loginResponse.accessToken())); + + // then + result.andExpect(status().isOk()); + result.andDo(document("get-coupon-by-coupon-number", + resource(ResourceSnippetParameters.builder() + .tag(RESOURCE_TAG) + .description("쿠폰 번호로 쿠폰 조회 API") + .responseSchema(Schema.schema(CouponResponse.class.getSimpleName())) + .responseFields( + fieldWithPath("title").type(JsonFieldType.STRING).description("쿠폰의 이름"), + fieldWithPath("coupon_number").type(JsonFieldType.STRING).description("쿠폰 번호"), + fieldWithPath("coupon_status").type(JsonFieldType.STRING).description("쿠폰 상태"), + fieldWithPath("coupon_concat_title").type(JsonFieldType.STRING).description("고객 유형 + 할인 유형 + 할인의 값"), + fieldWithPath("discount_type").type(JsonFieldType.STRING).description("할인의 유형"), + fieldWithPath("discount_value").type(JsonFieldType.NUMBER).description("할인의 값"), + fieldWithPath("customer_type").type(JsonFieldType.STRING).description("고객의 유형"), + fieldWithPath("coupon_room_type").type(JsonFieldType.STRING).description("객실의 유형"), + fieldWithPath("minimum_reservation_price").type(JsonFieldType.NUMBER).description("최소 예약 가격"), + fieldWithPath("coupon_use_condition_days").type(JsonFieldType.STRING).description("쿠폰 사용 가능 요일"), + fieldWithPath("exposure_start_date").type(JsonFieldType.STRING).description("노출 시작 날짜"), + fieldWithPath("exposure_end_date").type(JsonFieldType.STRING).description("노출 종료 날짜"), + fieldWithPath("coupon_expiration").type(JsonFieldType.NUMBER).description("쿠폰 만료 일자"), + fieldWithPath("download_count").type(JsonFieldType.NUMBER).description("다운로드 횟수"), + fieldWithPath("use_count").type(JsonFieldType.NUMBER).description("사용 수"), + fieldWithPath("accommodation_id").type(JsonFieldType.NUMBER).description("숙박업체의 ID"), + fieldWithPath("register_room_numbers").type(JsonFieldType.ARRAY).description("등록된 객실 번호"), + fieldWithPath("created_date").type(JsonFieldType.STRING).description("생성 날짜") + ) + .build() + ) + )); + } + @DisplayName("쿠폰 수정") @Test void updateCoupon_success() throws Exception { @@ -319,6 +367,7 @@ void updateCoupon_success() throws Exception { Coupon coupon = couponRepository.save(new CouponTestBuilder(accommodation, storedMember, randomRooms).build()); coupon.generateCouponNumber(CouponIssuerType.OWNER, coupon.getId()); CouponUpdateRequest request = new CouponUpdateRequest( + coupon.getTitle(), accommodation.getId(), coupon.getCustomerType().getValue(), coupon.getDiscountType().getValue(), @@ -327,7 +376,7 @@ void updateCoupon_success() throws Exception { coupon.getCouponRooms().isEmpty(), coupon.getCouponRooms().stream().map(room -> room.getRoom().getRoomNumber()).toList(), coupon.getMinimumReservationPrice() + 10000, - DayOfWeekUtil.fromDayOfWeeks(coupon.getCouponUseConditionDays()), + coupon.getCouponUseDays().getValue(), coupon.getExposureStartDate(), coupon.getExposureEndDate() ); @@ -348,6 +397,7 @@ void updateCoupon_success() throws Exception { .description("쿠폰 수정 API") .requestSchema(Schema.schema(CouponUpdateRequest.class.getSimpleName())) .requestFields( + fieldWithPath("title").type(JsonFieldType.STRING).description("쿠폰의 이름"), fieldWithPath("accommodation_id").type(JsonFieldType.NUMBER).description("숙박업체의 ID"), fieldWithPath("customer_type").type(JsonFieldType.STRING).description("고객의 유형").optional(), fieldWithPath("discount_type").type(JsonFieldType.STRING).description("할인의 유형").optional(), @@ -356,7 +406,7 @@ void updateCoupon_success() throws Exception { fieldWithPath("register_all_room").type(JsonFieldType.BOOLEAN).description("객실 등록 여부").optional(), fieldWithPath("register_rooms").type(JsonFieldType.ARRAY).description("등록될 객실의 리스트").optional(), fieldWithPath("minimum_reservation_price").type(JsonFieldType.NUMBER).description("최소 예약 가격").optional(), - fieldWithPath("coupon_use_condition_days").type(JsonFieldType.ARRAY).description("쿠폰 사용 가능 요일").optional(), + fieldWithPath("coupon_use_condition_days").type(JsonFieldType.STRING).description("쿠폰 사용 가능 요일").optional(), fieldWithPath("exposure_start_date").type(JsonFieldType.STRING).description("노출 시작 날짜").optional(), fieldWithPath("exposure_end_date").type(JsonFieldType.STRING).description("노출 종료 날짜").optional() ) diff --git a/src/test/java/com/coolpeace/domain/coupon/service/CouponServiceTest.java b/src/test/java/com/coolpeace/domain/coupon/service/CouponServiceTest.java index 7f7e7a31..791ce1e6 100644 --- a/src/test/java/com/coolpeace/domain/coupon/service/CouponServiceTest.java +++ b/src/test/java/com/coolpeace/domain/coupon/service/CouponServiceTest.java @@ -12,7 +12,9 @@ import com.coolpeace.domain.coupon.dto.response.CouponResponse; import com.coolpeace.domain.coupon.entity.Coupon; import com.coolpeace.domain.coupon.entity.type.*; -import com.coolpeace.domain.coupon.exception.*; +import com.coolpeace.domain.coupon.exception.CouponAccessDeniedException; +import com.coolpeace.domain.coupon.exception.CouponNotFoundException; +import com.coolpeace.domain.coupon.exception.InvalidCouponStateOutsideExposureDateException; import com.coolpeace.domain.coupon.repository.CouponRepository; import com.coolpeace.domain.member.entity.Member; import com.coolpeace.domain.member.exception.MemberNotFoundException; @@ -25,7 +27,6 @@ import com.coolpeace.global.builder.CouponTestBuilder; import com.coolpeace.global.builder.MemberTestBuilder; import com.coolpeace.global.builder.RoomTestBuilder; -import com.coolpeace.global.common.DayOfWeekUtil; import com.coolpeace.global.util.CouponTestUtil; import com.coolpeace.global.util.RoomTestUtil; import org.junit.jupiter.api.BeforeEach; @@ -47,7 +48,6 @@ import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.annotation.Transactional; -import java.time.DayOfWeek; import java.time.LocalDate; import java.util.*; import java.util.function.Predicate; @@ -324,7 +324,7 @@ private CouponRegisterRequest getCouponRegisterRequest(boolean registerAllRoom) registerAllRoom, !registerAllRoom ? registerRoomNumbers : null, coupon.getMinimumReservationPrice(), - DayOfWeekUtil.fromDayOfWeeks(coupon.getCouponUseConditionDays()), + coupon.getCouponUseDays().getValue(), coupon.getExposureStartDate(), coupon.getExposureEndDate() ); @@ -345,7 +345,7 @@ void beforeEach() { CustomerType.ALL_CLIENT, CouponRoomType.LODGE, 0, - Collections.emptyList(), + CouponUseDaysType.ALL, LocalDate.now().plusDays(100), LocalDate.now().plusDays(130), accommodation, @@ -362,7 +362,7 @@ void beforeEach() { CustomerType.FIRST_CLIENT, CouponRoomType.RENTAL, 1000, - List.of(DayOfWeek.MONDAY), + CouponUseDaysType.WEEKDAY, LocalDate.now().plusDays(30), LocalDate.now().plusDays(60), accommodation, @@ -378,7 +378,9 @@ void beforeEach() { void updateCoupon_mono_update_success() { //when - executeUpdateCoupon(new CouponUpdateRequest(accommodation.getId(), + executeUpdateCoupon(new CouponUpdateRequest( + couponB.getTitle(), + accommodation.getId(), couponB.getCustomerType().getValue(), null, null, @@ -386,7 +388,7 @@ void updateCoupon_mono_update_success() { null, null, couponB.getMinimumReservationPrice(), - DayOfWeekUtil.fromDayOfWeeks(couponB.getCouponUseConditionDays()), + couponB.getCouponUseDays().getValue(), couponB.getExposureStartDate(), couponB.getExposureEndDate() )); @@ -405,7 +407,9 @@ void updateCoupon_mono_update_success() { void updateCoupon_discountType_update_success() { //when - executeUpdateCoupon(new CouponUpdateRequest(accommodation.getId(), + executeUpdateCoupon(new CouponUpdateRequest( + null, + accommodation.getId(), null, couponB.getDiscountType().getValue(), couponB.getDiscountValue(), diff --git a/src/test/java/com/coolpeace/global/builder/CouponTestBuilder.java b/src/test/java/com/coolpeace/global/builder/CouponTestBuilder.java index 24bcde3d..9333cc11 100644 --- a/src/test/java/com/coolpeace/global/builder/CouponTestBuilder.java +++ b/src/test/java/com/coolpeace/global/builder/CouponTestBuilder.java @@ -3,16 +3,14 @@ import com.coolpeace.domain.accommodation.entity.Accommodation; import com.coolpeace.domain.coupon.entity.Coupon; import com.coolpeace.domain.coupon.entity.type.CouponRoomType; +import com.coolpeace.domain.coupon.entity.type.CouponUseDaysType; import com.coolpeace.domain.coupon.entity.type.CustomerType; import com.coolpeace.domain.coupon.entity.type.DiscountType; import com.coolpeace.domain.member.entity.Member; import com.coolpeace.domain.room.entity.Room; import com.github.javafaker.Faker; -import java.time.DayOfWeek; import java.time.LocalDate; -import java.util.Arrays; -import java.util.Collections; import java.util.List; public class CouponTestBuilder { @@ -68,15 +66,7 @@ public Coupon build() { boolean checkMinReservationPrice = faker.random().nextBoolean(); int minimumReservationPrice = checkMinReservationPrice ? faker.random().nextInt(1, 100) * 100 : 0; - boolean checkUseConditionDays = faker.random().nextBoolean(); - List useConditionDays; - if (checkUseConditionDays) { - List allDays = Arrays.asList(DayOfWeek.values()); - Collections.shuffle(allDays); - useConditionDays = allDays.subList(0, faker.random().nextInt(allDays.size())); - } else { - useConditionDays = Collections.emptyList(); - } + CouponUseDaysType couponUseDays = CouponUseDaysType.values()[faker.random().nextInt(CouponUseDaysType.values().length)]; if (exposureStartDate == null || exposureEndDate == null) { long startDate = faker.number().numberBetween(-200, 200); @@ -93,7 +83,7 @@ public Coupon build() { customerType, couponRoomType, minimumReservationPrice, - useConditionDays, + couponUseDays, exposureStartDate, exposureEndDate, accommodation,