From 7c0a26c3ddd18508916691e938fb95959f774e4f Mon Sep 17 00:00:00 2001 From: KwonJuHwan <118177454+KwonJuHwan@users.noreply.github.com> Date: Sun, 28 Jan 2024 01:37:33 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[feat]=20=EC=9D=BC=EB=B3=84=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20API=EC=97=90=20=EC=BF=A0=ED=8F=B0=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=B3=80=EA=B2=BD=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/statistics/controller/StatisticsController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java b/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java index da602590..d51ab6c4 100644 --- a/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java +++ b/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java @@ -28,6 +28,8 @@ public ResponseEntity dailyStatisticsSetting( dailyStatisticsService.updateSales(year,month,day); dailyStatisticsService.updateCoupon(year,month,day); dailyStatisticsService.updateSettlement(year,month,day); + dailyStatisticsService.updateCouponStatusStartExposure(); + return ResponseEntity.created(URI.create("/")).build(); From 20d4f4c97cc61b229899117e6a518885d608154a Mon Sep 17 00:00:00 2001 From: KwonJuHwan <118177454+KwonJuHwan@users.noreply.github.com> Date: Sun, 28 Jan 2024 02:03:04 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[feat]=20=EC=9D=BC=EB=B3=84=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=20API=EC=97=90=20=EC=BF=A0=ED=8F=B0=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=20=EC=A2=85=EB=A3=8C=20=EC=83=81=ED=83=9C=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/statistics/controller/StatisticsController.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java b/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java index d51ab6c4..355e4ec6 100644 --- a/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java +++ b/src/main/java/com/coolpeace/domain/statistics/controller/StatisticsController.java @@ -29,6 +29,7 @@ public ResponseEntity dailyStatisticsSetting( dailyStatisticsService.updateCoupon(year,month,day); dailyStatisticsService.updateSettlement(year,month,day); dailyStatisticsService.updateCouponStatusStartExposure(); + dailyStatisticsService.updateCouponStatusEndExposure(); From f8207343a9581a4663795fdcd3f0048561a14568 Mon Sep 17 00:00:00 2001 From: rightpair Date: Mon, 29 Jan 2024 15:48:22 +0900 Subject: [PATCH 3/4] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 데모 웹사이트 URL 수정 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3741637e..01ecde4c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@
배포된 API 서버 / - 데모 웹사이트 + 데모 웹사이트

From 028d15ad4d61c4d706a275cd878fe9824c45f403 Mon Sep 17 00:00:00 2001 From: rightpair Date: Tue, 30 Jan 2024 17:18:25 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[feature]=20CouponGuestService=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 설명: - #225 를 참고하세요. --- .../coupon/controller/CouponController.java | 23 ++- .../coupon/service/CouponGuestService.java | 168 ++++++++++++++++++ .../global/jwt/security/JwtPrincipal.java | 11 +- 3 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/coolpeace/domain/coupon/service/CouponGuestService.java 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 ca4d6547..0fccf21f 100644 --- a/src/main/java/com/coolpeace/domain/coupon/controller/CouponController.java +++ b/src/main/java/com/coolpeace/domain/coupon/controller/CouponController.java @@ -4,6 +4,7 @@ import com.coolpeace.domain.coupon.dto.request.CouponRegisterRequest; import com.coolpeace.domain.coupon.dto.request.CouponUpdateRequest; import com.coolpeace.domain.coupon.dto.response.CouponResponse; +import com.coolpeace.domain.coupon.service.CouponGuestService; import com.coolpeace.domain.coupon.service.CouponService; import com.coolpeace.global.jwt.security.JwtPrincipal; import com.coolpeace.global.resolver.AuthJwtPrincipal; @@ -20,6 +21,7 @@ @RequiredArgsConstructor public class CouponController { private final CouponService couponService; + private final CouponGuestService couponGuestService; @GetMapping("/{coupon_number}") public ResponseEntity getCouponByCouponNumber( @@ -45,7 +47,11 @@ public ResponseEntity registerCoupon( @Valid @RequestBody CouponRegisterRequest couponRegisterRequest, @AuthJwtPrincipal JwtPrincipal jwtPrincipal ) { - couponService.register(Long.valueOf(jwtPrincipal.getMemberId()), couponRegisterRequest); + if (jwtPrincipal.isGuestUser()) { + couponGuestService.register(Long.valueOf(jwtPrincipal.getMemberId()), couponRegisterRequest); + } else { + couponService.register(Long.valueOf(jwtPrincipal.getMemberId()), couponRegisterRequest); + } return ResponseEntity.created(URI.create("/")).build(); } @@ -54,8 +60,13 @@ public ResponseEntity updateCoupon( @PathVariable("coupon_number") String couponNumber, @Valid @RequestBody CouponUpdateRequest couponUpdateRequest, @AuthJwtPrincipal JwtPrincipal jwtPrincipal) { - couponService.updateCoupon( - Long.valueOf(jwtPrincipal.getMemberId()), couponNumber, couponUpdateRequest); + if (jwtPrincipal.isGuestUser()) { + couponGuestService.updateCoupon( + Long.valueOf(jwtPrincipal.getMemberId()), couponNumber, couponUpdateRequest); + } else { + couponService.updateCoupon( + Long.valueOf(jwtPrincipal.getMemberId()), couponNumber, couponUpdateRequest); + } return ResponseEntity.ok().build(); } @@ -75,7 +86,11 @@ public ResponseEntity deleteCoupon( @PathVariable("coupon_number") String couponNumber, @AuthJwtPrincipal JwtPrincipal jwtPrincipal ) { - couponService.deleteCoupon(Long.valueOf(jwtPrincipal.getMemberId()), couponNumber); + if (jwtPrincipal.isGuestUser()) { + couponGuestService.deleteCoupon(Long.valueOf(jwtPrincipal.getMemberId()), couponNumber); + } else { + couponService.deleteCoupon(Long.valueOf(jwtPrincipal.getMemberId()), couponNumber); + } return ResponseEntity.ok().build(); } } diff --git a/src/main/java/com/coolpeace/domain/coupon/service/CouponGuestService.java b/src/main/java/com/coolpeace/domain/coupon/service/CouponGuestService.java new file mode 100644 index 00000000..58654ecc --- /dev/null +++ b/src/main/java/com/coolpeace/domain/coupon/service/CouponGuestService.java @@ -0,0 +1,168 @@ +package com.coolpeace.domain.coupon.service; + +import com.coolpeace.domain.accommodation.entity.Accommodation; +import com.coolpeace.domain.accommodation.exception.AccommodationNotFoundException; +import com.coolpeace.domain.accommodation.repository.AccommodationRepository; +import com.coolpeace.domain.coupon.dto.request.CouponRegisterRequest; +import com.coolpeace.domain.coupon.dto.request.CouponUpdateRequest; +import com.coolpeace.domain.coupon.dto.request.type.DtoCouponUseDayOfWeekType; +import com.coolpeace.domain.coupon.dto.request.type.DtoCouponUseDaysType; +import com.coolpeace.domain.coupon.entity.Coupon; +import com.coolpeace.domain.coupon.entity.type.*; +import com.coolpeace.domain.coupon.exception.CouponAccessDeniedException; +import com.coolpeace.domain.coupon.exception.CouponNotFoundException; +import com.coolpeace.domain.coupon.repository.CouponRepository; +import com.coolpeace.domain.member.entity.Member; +import com.coolpeace.domain.member.exception.MemberNotFoundException; +import com.coolpeace.domain.member.repository.MemberRepository; +import com.coolpeace.domain.room.entity.Room; +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.ValuedEnum; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +@RequiredArgsConstructor +@Service +public class CouponGuestService { + + private final MemberRepository memberRepository; + private final CouponRepository couponRepository; + private final AccommodationRepository accommodationRepository; + private final RoomRepository roomRepository; + + @Transactional + public void register(Long memberId, CouponRegisterRequest couponRegisterRequest) { + Member storedMember = memberRepository.findById(memberId) + .orElseThrow(MemberNotFoundException::new); + Accommodation accommodation = accommodationRepository.findById( + couponRegisterRequest.accommodationId()) + .orElseThrow(AccommodationNotFoundException::new); + + List rooms; + if (!couponRegisterRequest.registerAllRoom()) { + if (CollectionUtils.isEmpty(couponRegisterRequest.registerRooms())) { + throw new RegisterRoomsEmptyException(); + } + rooms = couponRegisterRequest.registerRooms() + .stream().map(roomNumber -> roomRepository.findByRoomNumber(roomNumber) + .orElseThrow(RoomNotFoundException::new)) + .toList(); + } else { + rooms = Collections.emptyList(); + } + + DiscountType discountType = ValuedEnum.of(DiscountType.class, + couponRegisterRequest.discountType()); + Integer discountValue = switch (discountType) { + case FIXED_RATE -> couponRegisterRequest.discountFlatRate(); + case FIXED_PRICE -> couponRegisterRequest.discountFlatValue(); + }; + + CouponRoomType couponRoomTypeValue = getCouponRoomType( + couponRegisterRequest.couponRoomTypes(), CouponRoomType.RENTAL); + CouponRoomType couponRoomStayTypeValue = getCouponRoomStayTypeValue( + couponRegisterRequest.couponRoomTypes(), couponRoomTypeValue); + + CouponUseDaysType couponUseDays = getCouponUseDays( + couponRegisterRequest.couponUseConditionDays(), + couponRegisterRequest.couponUseConditionDayOfWeek()); + } + + private CouponUseDaysType getCouponUseDays(String couponUseDaysStr, String couponUseDayOfWeekStr) { + if (!StringUtils.hasText(couponUseDaysStr)) { + return CouponUseDaysType.ALL; + } + DtoCouponUseDaysType dtoCouponUseDaysType = ValuedEnum.of(DtoCouponUseDaysType.class, couponUseDaysStr); + return switch (dtoCouponUseDaysType) { + case ONEDAY -> CouponUseDaysType.valueOf( + ValuedEnum.of(DtoCouponUseDayOfWeekType.class, couponUseDayOfWeekStr).name()); + case WEEKDAY -> CouponUseDaysType.WEEKDAY; + case WEEKEND -> CouponUseDaysType.WEEKEND; + }; + } + + @Transactional + public void updateCoupon(Long memberId, String couponNumber, + CouponUpdateRequest couponUpdateRequest) { + validateMemberHasCoupon(memberId, couponNumber); + Coupon storedCoupon = couponRepository.findByCouponNumber(couponNumber) + .orElseThrow(CouponNotFoundException::new); + List rooms; + if (couponUpdateRequest.registerRooms() != null) { + rooms = couponUpdateRequest.registerRooms() + .stream().map(roomNumber -> roomRepository.findByRoomNumber(roomNumber) + .orElseThrow(RoomNotFoundException::new)) + .toList(); + } else { + rooms = Collections.emptyList(); + } + + DiscountType discountType = Optional.ofNullable(couponUpdateRequest.discountType()) + .map(str -> ValuedEnum.of(DiscountType.class, str)) + .orElse(null); + + Integer discountValue = null; + if (discountType != null) { + discountValue = switch (discountType) { + case FIXED_RATE -> couponUpdateRequest.discountFlatRate(); + case FIXED_PRICE -> couponUpdateRequest.discountFlatValue(); + }; + } + + CustomerType customerType = Optional.ofNullable(couponUpdateRequest.customerType()) + .map(str -> ValuedEnum.of(CustomerType.class, str)) + .orElse(null); + + CouponRoomType couponRoomTypeValue = getCouponRoomType( + couponUpdateRequest.couponRoomTypes(), CouponRoomType.RENTAL); + CouponRoomType couponRoomStayTypeValue = getCouponRoomStayTypeValue( + couponUpdateRequest.couponRoomTypes(), couponRoomTypeValue); + + CouponUseDaysType couponUseDays = Optional.ofNullable(couponUpdateRequest.couponUseConditionDays()) + .map(str -> getCouponUseDays( + couponUpdateRequest.couponUseConditionDays(), + couponUpdateRequest.couponUseConditionDayOfWeek())) + .orElse(null); + } + + private CouponRoomType getCouponRoomStayTypeValue(List couponRoomTypeStrings, + CouponRoomType couponRoomTypeRentalValue) { + if (couponRoomTypeRentalValue != null) { + return null; + } + CouponRoomType couponRoomType = getCouponRoomType(couponRoomTypeStrings, CouponRoomType.LODGE); + if (couponRoomType == null) { + return getCouponRoomType(couponRoomTypeStrings, CouponRoomType.TWO_NIGHT); + } + return couponRoomType; + } + + private CouponRoomType getCouponRoomType(List request, CouponRoomType couponRoomType) { + return request.stream() + .map(str -> ValuedEnum.of(CouponRoomType.class, str)) + .filter(roomType -> roomType.equals(couponRoomType)) + .findFirst().orElse(null); + } + + @Transactional + public void deleteCoupon(Long memberId, String couponNumber) { + validateMemberHasCoupon(memberId, couponNumber); + Coupon storedCoupon = couponRepository.findByCouponNumber(couponNumber) + .orElseThrow(CouponNotFoundException::new); + } + + public void validateMemberHasCoupon(Long memberId, String couponNumber) { + if (!couponRepository.existsByMemberIdAndCouponNumber(memberId, couponNumber)) { + throw new CouponAccessDeniedException(); + } + } +} diff --git a/src/main/java/com/coolpeace/global/jwt/security/JwtPrincipal.java b/src/main/java/com/coolpeace/global/jwt/security/JwtPrincipal.java index 63556202..da4628a6 100644 --- a/src/main/java/com/coolpeace/global/jwt/security/JwtPrincipal.java +++ b/src/main/java/com/coolpeace/global/jwt/security/JwtPrincipal.java @@ -1,6 +1,7 @@ package com.coolpeace.global.jwt.security; import com.coolpeace.domain.member.entity.Member; +import com.coolpeace.domain.member.entity.type.RoleType; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; @@ -18,13 +19,16 @@ public class JwtPrincipal implements UserDetails { private final String memberId; private final String memberEmail; private final boolean enabled; + private final boolean isGuestUser; private final List authorities; - public JwtPrincipal(String memberId, String memberEmail, boolean enabled, List authorities) { + public JwtPrincipal(String memberId, String memberEmail, boolean enabled, + List authorities, boolean isGuestUser) { this.memberId = memberId; this.memberEmail = memberEmail; this.enabled = enabled; this.authorities = authorities; + this.isGuestUser = isGuestUser; } public static JwtPrincipal from(Member member) { @@ -35,11 +39,12 @@ public static JwtPrincipal from(Member member) { String.valueOf(member.getId()), member.getEmail(), !member.isDeleted(), - AuthorityUtils.createAuthorityList(roles) + AuthorityUtils.createAuthorityList(roles), + roles.contains(RoleType.USER.getValue()) ); } public static JwtPrincipal emptyPrincipal() { - return new JwtPrincipal(null, null, false, AuthorityUtils.NO_AUTHORITIES); + return new JwtPrincipal(null, null, false, AuthorityUtils.NO_AUTHORITIES, false); } @Override