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