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