Compare commits
2 Commits
feature/mo
...
feature/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e2ba4abae | ||
|
|
4abebf9a8c |
@@ -18,6 +18,7 @@ public enum ErrorCode {
|
|||||||
UNAVAILABLE_REFRESH_TOKEN(BAD_REQUEST, "사용할 수 없는 토큰 입니다."),
|
UNAVAILABLE_REFRESH_TOKEN(BAD_REQUEST, "사용할 수 없는 토큰 입니다."),
|
||||||
|
|
||||||
/* 404 NOT_FOUND : Resource 를 찾을 수 없음 */
|
/* 404 NOT_FOUND : Resource 를 찾을 수 없음 */
|
||||||
|
USER_NOT_FOUND(NOT_FOUND, "해당 유저 정보를 찾을 수 없습니다."),
|
||||||
EMAIL_NOT_FOUND(NOT_FOUND, "해당 이메일을 찾을 수 없습니다."),
|
EMAIL_NOT_FOUND(NOT_FOUND, "해당 이메일을 찾을 수 없습니다."),
|
||||||
MOVIE_NOT_FOUND(NOT_FOUND, "해당 제목의 영화를 찾을 수 없습니다."),
|
MOVIE_NOT_FOUND(NOT_FOUND, "해당 제목의 영화를 찾을 수 없습니다."),
|
||||||
REFRESH_TOKEN_NOT_FOUND(NOT_FOUND, "리프레쉬 토큰을 찾을 수 없습니다."),
|
REFRESH_TOKEN_NOT_FOUND(NOT_FOUND, "리프레쉬 토큰을 찾을 수 없습니다."),
|
||||||
@@ -29,4 +30,43 @@ public enum ErrorCode {
|
|||||||
private final HttpStatus httpStatus;
|
private final HttpStatus httpStatus;
|
||||||
private final String detail;
|
private final String detail;
|
||||||
|
|
||||||
|
/* 400 BAD_REQUEST : 잘못된 요청 */
|
||||||
|
public static TicketingException throwMismatchPassword() {
|
||||||
|
throw new TicketingException(MISMATCH_PASSWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TicketingException throwTokenType() {
|
||||||
|
throw new TicketingException(TOKEN_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TicketingException throwUnavailableRefreshToken() {
|
||||||
|
throw new TicketingException(UNAVAILABLE_REFRESH_TOKEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 404 NOT_FOUND : Resource 를 찾을 수 없음 */
|
||||||
|
public static TicketingException throwUserNotFound() {
|
||||||
|
throw new TicketingException(USER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TicketingException throwEmailNotFound() {
|
||||||
|
throw new TicketingException(EMAIL_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TicketingException throwMovieNotFound() {
|
||||||
|
throw new TicketingException(MOVIE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TicketingException throwRefreshTokenNotFound() {
|
||||||
|
throw new TicketingException(REFRESH_TOKEN_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 409 CONFLICT : Resource 의 현재 상태와 충돌. 보통 중복된 데이터 존재 */
|
||||||
|
public static TicketingException throwDuplicateEmail() {
|
||||||
|
throw new TicketingException(DUPLICATE_EMAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TicketingException throwDeletedEmail() {
|
||||||
|
throw new TicketingException(DELETED_EMAIL);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ public class Seat extends AbstractEntity {
|
|||||||
@JoinColumn(name = "theater_id", referencedColumnName = "id", updatable = false)
|
@JoinColumn(name = "theater_id", referencedColumnName = "id", updatable = false)
|
||||||
private Theater theater;
|
private Theater theater;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Integer seatColumn;
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Integer seatRow;
|
private Integer seatRow;
|
||||||
|
|
||||||
public Seat(Integer seatColumn, Integer seatRow, Theater theater) {
|
@NotNull
|
||||||
this.seatColumn = seatColumn;
|
private Integer seatColumn;
|
||||||
|
|
||||||
|
public Seat(Integer seatRow, Integer seatColumn, Theater theater) {
|
||||||
this.seatRow = seatRow;
|
this.seatRow = seatRow;
|
||||||
|
this.seatColumn = seatColumn;
|
||||||
setTheater(theater);
|
setTheater(theater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.ticketing.server.movie.domain;
|
package com.ticketing.server.movie.domain;
|
||||||
|
|
||||||
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
||||||
import com.ticketing.server.payment.domain.Payment;
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
@@ -26,9 +25,7 @@ public class Ticket extends AbstractEntity {
|
|||||||
@JoinColumn(name = "movie_times_id", referencedColumnName = "id", updatable = false)
|
@JoinColumn(name = "movie_times_id", referencedColumnName = "id", updatable = false)
|
||||||
private MovieTime movieTime;
|
private MovieTime movieTime;
|
||||||
|
|
||||||
@ManyToOne
|
private Long paymentId;
|
||||||
@JoinColumn(name = "payment_id", referencedColumnName = "id", updatable = false)
|
|
||||||
private Payment payment;
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package com.ticketing.server.movie.service;
|
package com.ticketing.server.movie.service;
|
||||||
|
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.MOVIE_NOT_FOUND;
|
import com.ticketing.server.global.exception.ErrorCode;
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.TicketingException;
|
|
||||||
import com.ticketing.server.movie.domain.Movie;
|
import com.ticketing.server.movie.domain.Movie;
|
||||||
import com.ticketing.server.movie.domain.MovieTime;
|
import com.ticketing.server.movie.domain.MovieTime;
|
||||||
import com.ticketing.server.movie.domain.repository.MovieRepository;
|
import com.ticketing.server.movie.domain.repository.MovieRepository;
|
||||||
@@ -22,28 +20,24 @@ import org.springframework.stereotype.Service;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class MovieTimeServiceImpl implements MovieTimeService {
|
public class MovieTimeServiceImpl implements MovieTimeService {
|
||||||
|
|
||||||
private final MovieRepository movieRepository;
|
private final MovieRepository movieRepository;
|
||||||
|
|
||||||
private final MovieTimeRepository movieTimeRepository;
|
private final MovieTimeRepository movieTimeRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MovieTimeDto> getMovieTimes(String title, LocalDate runningDate) {
|
public List<MovieTimeDto> getMovieTimes(String title, LocalDate runningDate) {
|
||||||
Movie movie = movieRepository.findByTitle(title)
|
Movie movie = movieRepository.findByTitle(title)
|
||||||
.orElseThrow(MovieTimeServiceImpl::throwMovieNotFound);
|
.orElseThrow(ErrorCode::throwMovieNotFound);
|
||||||
|
|
||||||
LocalDateTime startOfDay = runningDate.atStartOfDay().plusHours(6);
|
LocalDateTime startOfDay = runningDate.atStartOfDay().plusHours(6);
|
||||||
LocalDateTime endOfDay = startOfDay.plusDays(1);
|
LocalDateTime endOfDay = startOfDay.plusDays(1);
|
||||||
|
|
||||||
List<MovieTime> movieTimes = movieTimeRepository.findValidMovieTimes(movie, startOfDay, endOfDay);
|
List<MovieTime> movieTimes = movieTimeRepository.findValidMovieTimes(movie, startOfDay, endOfDay);
|
||||||
|
|
||||||
return movieTimes.stream()
|
return movieTimes.stream()
|
||||||
.map(MovieTimeDto::from)
|
.map(MovieTimeDto::from)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RuntimeException throwMovieNotFound() {
|
|
||||||
throw new TicketingException(MOVIE_NOT_FOUND);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class MovieSetupService {
|
public class
|
||||||
|
MovieSetupService {
|
||||||
|
|
||||||
private final MovieRepository movieRepository;
|
private final MovieRepository movieRepository;
|
||||||
private final MovieTimeRepository movieTimeRepository;
|
private final MovieTimeRepository movieTimeRepository;
|
||||||
@@ -53,9 +54,9 @@ public class MovieSetupService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (Theater theater : theaters) {
|
for (Theater theater : theaters) {
|
||||||
for (int i = 1; i <= 2; i++) {
|
for (int row = 1; row <= 2; row++) {
|
||||||
for (int j = 1; j <= 10; j++) {
|
for (int col = 1; col <= 10; col++) {
|
||||||
new Seat(i, j, theater);
|
new Seat(row, col, theater);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
package com.ticketing.server.payment.domain;
|
package com.ticketing.server.payment.domain;
|
||||||
|
|
||||||
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.payment.service.dto.CreatePaymentDto;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.EnumType;
|
import javax.persistence.EnumType;
|
||||||
import javax.persistence.Enumerated;
|
import javax.persistence.Enumerated;
|
||||||
import javax.persistence.JoinColumn;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.persistence.ManyToOne;
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Getter
|
@Getter
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PROTECTED)
|
||||||
public class Payment extends AbstractEntity {
|
public class Payment extends AbstractEntity {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@ManyToOne
|
private Long userId;
|
||||||
@JoinColumn(name = "user_id", referencedColumnName = "id", updatable = false)
|
|
||||||
private User user;
|
@NotEmpty
|
||||||
|
private String movieTitle;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Enumerated(value = EnumType.STRING)
|
@Enumerated(value = EnumType.STRING)
|
||||||
@@ -29,10 +32,28 @@ public class Payment extends AbstractEntity {
|
|||||||
|
|
||||||
private String failedMessage;
|
private String failedMessage;
|
||||||
|
|
||||||
@NotNull
|
@NotEmpty
|
||||||
private String paymentNumber;
|
private String paymentNumber;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private Integer totalPrice;
|
private Integer totalPrice;
|
||||||
|
|
||||||
|
private Payment(Long userId, String movieTitle, PaymentType type, PaymentStatus status, String paymentNumber, Integer totalPrice) {
|
||||||
|
this.userId = userId;
|
||||||
|
this.movieTitle = movieTitle;
|
||||||
|
this.type = type;
|
||||||
|
this.status = status;
|
||||||
|
this.paymentNumber = paymentNumber;
|
||||||
|
this.totalPrice = totalPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Payment from(CreatePaymentDto dto) {
|
||||||
|
return new Payment(dto.getUserId(),
|
||||||
|
dto.getMovieTitle(),
|
||||||
|
dto.getType(),
|
||||||
|
dto.getStatus(),
|
||||||
|
dto.getPaymentNumber(),
|
||||||
|
dto.getTotalPrice());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.ticketing.server.payment.domain.repository;
|
package com.ticketing.server.payment.domain.repository;
|
||||||
|
|
||||||
import com.ticketing.server.payment.domain.Payment;
|
import com.ticketing.server.payment.domain.Payment;
|
||||||
|
import java.util.List;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface PaymentRepository extends JpaRepository<Payment, Long> {
|
public interface PaymentRepository extends JpaRepository<Payment, Long> {
|
||||||
|
|
||||||
|
List<Payment> findByUserId(Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,26 @@
|
|||||||
package com.ticketing.server.payment.service;
|
package com.ticketing.server.payment.service;
|
||||||
|
|
||||||
|
import com.ticketing.server.payment.domain.repository.PaymentRepository;
|
||||||
|
import com.ticketing.server.payment.service.dto.SimplePaymentDto;
|
||||||
import com.ticketing.server.payment.service.interfaces.PaymentService;
|
import com.ticketing.server.payment.service.interfaces.PaymentService;
|
||||||
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class PaymentServiceImpl implements PaymentService {
|
public class PaymentServiceImpl implements PaymentService {
|
||||||
|
|
||||||
|
private final PaymentRepository paymentRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SimplePaymentsResponse findSimplePayments(Long userId) {
|
||||||
|
return paymentRepository.findByUserId(userId)
|
||||||
|
.stream()
|
||||||
|
.map(SimplePaymentDto::from)
|
||||||
|
.collect(Collectors.collectingAndThen(Collectors.toList()
|
||||||
|
, list -> SimplePaymentsResponse.from(userId, list)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.ticketing.server.payment.service.dto;
|
||||||
|
|
||||||
|
import com.ticketing.server.payment.domain.PaymentStatus;
|
||||||
|
import com.ticketing.server.payment.domain.PaymentType;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class CreatePaymentDto {
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
private String movieTitle;
|
||||||
|
private PaymentType type;
|
||||||
|
private PaymentStatus status;
|
||||||
|
private String paymentNumber;
|
||||||
|
private Integer totalPrice;
|
||||||
|
|
||||||
|
public static CreatePaymentDto of(
|
||||||
|
Long userId,
|
||||||
|
String movieTitle,
|
||||||
|
PaymentType type,
|
||||||
|
PaymentStatus status,
|
||||||
|
String paymentNumber,
|
||||||
|
Integer totalPrice) {
|
||||||
|
return new CreatePaymentDto(userId, movieTitle, type, status, paymentNumber, totalPrice);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ticketing.server.payment.service.dto;
|
||||||
|
|
||||||
|
import com.ticketing.server.payment.domain.Payment;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class SimplePaymentDto {
|
||||||
|
|
||||||
|
private Long paymentId;
|
||||||
|
private String movieTitle;
|
||||||
|
private String paymentNumber;
|
||||||
|
private Integer totalPrice;
|
||||||
|
|
||||||
|
public static SimplePaymentDto from(Payment payment) {
|
||||||
|
return new SimplePaymentDto(
|
||||||
|
payment.getId(),
|
||||||
|
payment.getMovieTitle(),
|
||||||
|
payment.getPaymentNumber(),
|
||||||
|
payment.getTotalPrice()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
package com.ticketing.server.payment.service.interfaces;
|
package com.ticketing.server.payment.service.interfaces;
|
||||||
|
|
||||||
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
|
||||||
public interface PaymentService {
|
public interface PaymentService {
|
||||||
|
|
||||||
|
SimplePaymentsResponse findSimplePayments(Long userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.ticketing.server.user.api;
|
||||||
|
|
||||||
|
import com.ticketing.server.user.api.dto.request.SimplePaymentsRequest;
|
||||||
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
|
||||||
|
public interface PaymentClient {
|
||||||
|
|
||||||
|
SimplePaymentsResponse getSimplePayments(SimplePaymentsRequest request);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ticketing.server.user.api.dto.request;
|
||||||
|
|
||||||
|
import com.ticketing.server.user.domain.User;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class SimplePaymentsRequest {
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
public static SimplePaymentsRequest from(User user) {
|
||||||
|
return new SimplePaymentsRequest(user.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.ticketing.server.user.api.dto.response;
|
||||||
|
|
||||||
|
import com.ticketing.server.payment.service.dto.SimplePaymentDto;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class SimplePaymentsResponse {
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
private List<SimplePaymentDto> payments;
|
||||||
|
|
||||||
|
public static SimplePaymentsResponse from(Long userId, List<SimplePaymentDto> simplePayments) {
|
||||||
|
return new SimplePaymentsResponse(userId, simplePayments);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.ticketing.server.user.api.impl;
|
||||||
|
|
||||||
|
import com.ticketing.server.payment.service.PaymentServiceImpl;
|
||||||
|
import com.ticketing.server.user.api.PaymentClient;
|
||||||
|
import com.ticketing.server.user.api.dto.request.SimplePaymentsRequest;
|
||||||
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PaymentClientImpl implements PaymentClient {
|
||||||
|
|
||||||
|
private final PaymentServiceImpl paymentService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SimplePaymentsResponse getSimplePayments(SimplePaymentsRequest request) {
|
||||||
|
return paymentService.findSimplePayments(request.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.ticketing.server.user.application.request.SignUpRequest;
|
|||||||
import com.ticketing.server.user.application.request.UserChangePasswordRequest;
|
import com.ticketing.server.user.application.request.UserChangePasswordRequest;
|
||||||
import com.ticketing.server.user.application.request.UserDeleteRequest;
|
import com.ticketing.server.user.application.request.UserDeleteRequest;
|
||||||
import com.ticketing.server.user.application.response.SignUpResponse;
|
import com.ticketing.server.user.application.response.SignUpResponse;
|
||||||
|
import com.ticketing.server.user.application.response.SimplePaymentDetailsResponse;
|
||||||
import com.ticketing.server.user.application.response.UserChangePasswordResponse;
|
import com.ticketing.server.user.application.response.UserChangePasswordResponse;
|
||||||
import com.ticketing.server.user.application.response.UserDeleteResponse;
|
import com.ticketing.server.user.application.response.UserDeleteResponse;
|
||||||
import com.ticketing.server.user.application.response.UserDetailResponse;
|
import com.ticketing.server.user.application.response.UserDetailResponse;
|
||||||
@@ -65,4 +66,11 @@ public class UserController {
|
|||||||
return ResponseEntity.status(HttpStatus.OK).body(UserChangePasswordResponse.from(user));
|
return ResponseEntity.status(HttpStatus.OK).body(UserChangePasswordResponse.from(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/payments")
|
||||||
|
@Secured("ROLE_GUEST")
|
||||||
|
public ResponseEntity<SimplePaymentDetailsResponse> getPayments(@AuthenticationPrincipal UserDetails userRequest) {
|
||||||
|
SimplePaymentDetailsResponse paymentDetails = userService.findSimplePaymentDetails(userRequest.getUsername());
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(paymentDetails);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.ticketing.server.user.application.response;
|
||||||
|
|
||||||
|
import com.ticketing.server.payment.service.dto.SimplePaymentDto;
|
||||||
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class SimplePaymentDetailsResponse {
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
private List<SimplePaymentDto> payments;
|
||||||
|
|
||||||
|
public static SimplePaymentDetailsResponse of(String email, SimplePaymentsResponse paymentsResponse) {
|
||||||
|
return new SimplePaymentDetailsResponse(email, paymentsResponse.getPayments());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,10 +1,7 @@
|
|||||||
package com.ticketing.server.user.domain;
|
package com.ticketing.server.user.domain;
|
||||||
|
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.DELETED_EMAIL;
|
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.MISMATCH_PASSWORD;
|
|
||||||
|
|
||||||
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
||||||
import com.ticketing.server.global.exception.TicketingException;
|
import com.ticketing.server.global.exception.ErrorCode;
|
||||||
import com.ticketing.server.global.validator.constraints.Phone;
|
import com.ticketing.server.global.validator.constraints.Phone;
|
||||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||||
@@ -62,7 +59,7 @@ public class User extends AbstractEntity {
|
|||||||
|
|
||||||
public User delete(DeleteUserDTO deleteUser) {
|
public User delete(DeleteUserDTO deleteUser) {
|
||||||
if (isDeleted) {
|
if (isDeleted) {
|
||||||
throw new TicketingException(DELETED_EMAIL);
|
throw ErrorCode.throwDeletedEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPassword(deleteUser);
|
checkPassword(deleteUser);
|
||||||
@@ -81,7 +78,7 @@ public class User extends AbstractEntity {
|
|||||||
|
|
||||||
public void checkPassword(PasswordMatches passwordMatches) {
|
public void checkPassword(PasswordMatches passwordMatches) {
|
||||||
if (!passwordMatches.passwordMatches(password)) {
|
if (!passwordMatches.passwordMatches(password)) {
|
||||||
throw new TicketingException(MISMATCH_PASSWORD);
|
throw ErrorCode.throwMismatchPassword();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
package com.ticketing.server.user.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.REFRESH_TOKEN_NOT_FOUND;
|
import com.ticketing.server.global.exception.ErrorCode;
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.TOKEN_TYPE;
|
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.UNAVAILABLE_REFRESH_TOKEN;
|
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.TicketingException;
|
|
||||||
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
||||||
import com.ticketing.server.global.redis.RefreshToken;
|
import com.ticketing.server.global.redis.RefreshToken;
|
||||||
import com.ticketing.server.global.security.jwt.JwtProperties;
|
import com.ticketing.server.global.security.jwt.JwtProperties;
|
||||||
@@ -63,11 +59,11 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
|
|
||||||
// Redis 에 토큰이 있는지 검증
|
// Redis 에 토큰이 있는지 검증
|
||||||
RefreshToken findTokenEntity = refreshRedisRepository.findByEmail(authentication.getName())
|
RefreshToken findTokenEntity = refreshRedisRepository.findByEmail(authentication.getName())
|
||||||
.orElseThrow(() -> new TicketingException(REFRESH_TOKEN_NOT_FOUND));
|
.orElseThrow(ErrorCode::throwRefreshTokenNotFound);
|
||||||
|
|
||||||
// redis 토큰과 input 토큰이 일치한지 확인
|
// redis 토큰과 input 토큰이 일치한지 확인
|
||||||
if (!refreshToken.equals(findTokenEntity.getToken())) {
|
if (!refreshToken.equals(findTokenEntity.getToken())) {
|
||||||
throw new TicketingException(UNAVAILABLE_REFRESH_TOKEN);
|
throw ErrorCode.throwUnavailableRefreshToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 토큰 발급
|
// 토큰 발급
|
||||||
@@ -94,7 +90,7 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
if (StringUtils.hasText(bearerToken) && jwtProperties.hasTokenStartsWith(bearerToken)) {
|
if (StringUtils.hasText(bearerToken) && jwtProperties.hasTokenStartsWith(bearerToken)) {
|
||||||
return bearerToken.substring(7);
|
return bearerToken.substring(7);
|
||||||
}
|
}
|
||||||
throw new TicketingException(TOKEN_TYPE);
|
throw ErrorCode.throwTokenType();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package com.ticketing.server.user.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.EMAIL_NOT_FOUND;
|
import com.ticketing.server.global.exception.ErrorCode;
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.TicketingException;
|
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -23,7 +21,7 @@ public class CustomUserDetailsService implements UserDetailsService {
|
|||||||
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
||||||
return userRepository.findByEmailAndIsDeletedFalse(email)
|
return userRepository.findByEmailAndIsDeletedFalse(email)
|
||||||
.map(this::createUserDetails)
|
.map(this::createUserDetails)
|
||||||
.orElseThrow(() -> new TicketingException(EMAIL_NOT_FOUND));
|
.orElseThrow(ErrorCode::throwEmailNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserDetails createUserDetails(User user) {
|
private UserDetails createUserDetails(User user) {
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
package com.ticketing.server.user.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.DUPLICATE_EMAIL;
|
import com.ticketing.server.global.exception.ErrorCode;
|
||||||
import static com.ticketing.server.global.exception.ErrorCode.EMAIL_NOT_FOUND;
|
import com.ticketing.server.user.api.PaymentClient;
|
||||||
|
import com.ticketing.server.user.api.dto.request.SimplePaymentsRequest;
|
||||||
import com.ticketing.server.global.exception.TicketingException;
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
import com.ticketing.server.user.application.response.SimplePaymentDetailsResponse;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||||
@@ -26,6 +27,7 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
public class UserServiceImpl implements UserService {
|
public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
|
private final PaymentClient paymentClient;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -35,7 +37,7 @@ public class UserServiceImpl implements UserService {
|
|||||||
return userRepository.save(signUpDto.toUser());
|
return userRepository.save(signUpDto.toUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new TicketingException(DUPLICATE_EMAIL);
|
throw ErrorCode.throwDuplicateEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,16 +57,20 @@ public class UserServiceImpl implements UserService {
|
|||||||
@Override
|
@Override
|
||||||
public User findByEmail(String email) {
|
public User findByEmail(String email) {
|
||||||
return userRepository.findByEmail(email)
|
return userRepository.findByEmail(email)
|
||||||
.orElseThrow(UserServiceImpl::throwEmailNotFound);
|
.orElseThrow(ErrorCode::throwEmailNotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SimplePaymentDetailsResponse findSimplePaymentDetails(String email) {
|
||||||
|
User user = findNotDeletedUserByEmail(email);
|
||||||
|
SimplePaymentsResponse simplePayments = paymentClient.getSimplePayments(SimplePaymentsRequest.from(user));
|
||||||
|
|
||||||
|
return SimplePaymentDetailsResponse.of(email, simplePayments);
|
||||||
}
|
}
|
||||||
|
|
||||||
private User findNotDeletedUserByEmail(String email) {
|
private User findNotDeletedUserByEmail(String email) {
|
||||||
return userRepository.findByEmailAndIsDeletedFalse(email)
|
return userRepository.findByEmailAndIsDeletedFalse(email)
|
||||||
.orElseThrow(UserServiceImpl::throwEmailNotFound);
|
.orElseThrow(ErrorCode::throwEmailNotFound);
|
||||||
}
|
|
||||||
|
|
||||||
private static RuntimeException throwEmailNotFound() {
|
|
||||||
throw new TicketingException(EMAIL_NOT_FOUND);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ticketing.server.user.service.interfaces;
|
package com.ticketing.server.user.service.interfaces;
|
||||||
|
|
||||||
|
import com.ticketing.server.user.application.response.SimplePaymentDetailsResponse;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||||
@@ -15,4 +16,7 @@ public interface UserService {
|
|||||||
User changePassword(@Valid ChangePasswordDTO changePasswordDto);
|
User changePassword(@Valid ChangePasswordDTO changePasswordDto);
|
||||||
|
|
||||||
User findByEmail(String email);
|
User findByEmail(String email);
|
||||||
|
|
||||||
|
SimplePaymentDetailsResponse findSimplePaymentDetails(String email);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.ticketing.server.payment.service;
|
||||||
|
|
||||||
|
import static com.ticketing.server.payment.domain.PaymentStatus.COMPLETED;
|
||||||
|
import static com.ticketing.server.payment.domain.PaymentType.KAKAO_PAY;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import com.ticketing.server.payment.domain.Payment;
|
||||||
|
import com.ticketing.server.payment.domain.repository.PaymentRepository;
|
||||||
|
import com.ticketing.server.payment.service.dto.CreatePaymentDto;
|
||||||
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class PaymentServiceImplTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
PaymentRepository paymentRepository;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
PaymentServiceImpl paymentService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("유저 ID로 결제내역이 없을 경우")
|
||||||
|
void findSimplePaymentsZero() {
|
||||||
|
// given
|
||||||
|
when(paymentRepository.findByUserId(2L)).thenReturn(Collections.emptyList());
|
||||||
|
|
||||||
|
// when
|
||||||
|
SimplePaymentsResponse simplePayments = paymentService.findSimplePayments(2L);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertAll(
|
||||||
|
() -> assertThat(simplePayments.getUserId()).isEqualTo(2L)
|
||||||
|
, () -> assertThat(simplePayments.getPayments()).isEmpty()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@DisplayName("유저 ID로 간소 결제내역 조회 성공")
|
||||||
|
@ValueSource(longs = {1L, 2L, 100L, 154L})
|
||||||
|
void findSimplePaymentsSuccess(Long userId) {
|
||||||
|
// given
|
||||||
|
List<Payment> payments = Arrays.asList(
|
||||||
|
Payment.from(CreatePaymentDto.of(userId, "범죄도시2", KAKAO_PAY, COMPLETED, "004-323-77542", 15_000)),
|
||||||
|
Payment.from(CreatePaymentDto.of(userId, "토르", KAKAO_PAY, COMPLETED, "004-323-77544", 30_000))
|
||||||
|
);
|
||||||
|
when(paymentRepository.findByUserId(userId)).thenReturn(payments);
|
||||||
|
|
||||||
|
// when
|
||||||
|
SimplePaymentsResponse simplePayments = paymentService.findSimplePayments(userId);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertAll(
|
||||||
|
() -> assertThat(simplePayments.getUserId()).isEqualTo(userId)
|
||||||
|
, () -> assertThat(simplePayments.getPayments()).hasSize(2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.ticketing.server.user.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
|
import static com.ticketing.server.payment.domain.PaymentStatus.COMPLETED;
|
||||||
|
import static com.ticketing.server.payment.domain.PaymentType.KAKAO_PAY;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
@@ -7,6 +9,13 @@ import static org.mockito.ArgumentMatchers.any;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.TicketingException;
|
import com.ticketing.server.global.exception.TicketingException;
|
||||||
|
import com.ticketing.server.payment.domain.Payment;
|
||||||
|
import com.ticketing.server.payment.service.dto.CreatePaymentDto;
|
||||||
|
import com.ticketing.server.payment.service.dto.SimplePaymentDto;
|
||||||
|
import com.ticketing.server.user.api.PaymentClient;
|
||||||
|
import com.ticketing.server.user.api.dto.request.SimplePaymentsRequest;
|
||||||
|
import com.ticketing.server.user.api.dto.response.SimplePaymentsResponse;
|
||||||
|
import com.ticketing.server.user.application.response.SimplePaymentDetailsResponse;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.domain.UserGrade;
|
import com.ticketing.server.user.domain.UserGrade;
|
||||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||||
@@ -14,6 +23,8 @@ import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
|||||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||||
import com.ticketing.server.user.service.dto.DeleteUserDtoTest;
|
import com.ticketing.server.user.service.dto.DeleteUserDtoTest;
|
||||||
import com.ticketing.server.user.service.dto.SignUpDTO;
|
import com.ticketing.server.user.service.dto.SignUpDTO;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
@@ -34,6 +45,9 @@ class UserServiceImplTest {
|
|||||||
@Mock
|
@Mock
|
||||||
UserRepository userRepository;
|
UserRepository userRepository;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
PaymentClient paymentClient;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
UserServiceImpl userService;
|
UserServiceImpl userService;
|
||||||
|
|
||||||
@@ -124,4 +138,30 @@ class UserServiceImplTest {
|
|||||||
assertThat(user).isNotNull();
|
assertThat(user).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("회원 결제목록 조회")
|
||||||
|
void findSimplePaymentDetailsSuccess() {
|
||||||
|
// given
|
||||||
|
List<SimplePaymentDto> paymentDtos = Arrays.asList(
|
||||||
|
SimplePaymentDto.from(
|
||||||
|
Payment.from(
|
||||||
|
CreatePaymentDto.of(1L, "범죄도시2", KAKAO_PAY, COMPLETED, "004-323-77542", 15_000))),
|
||||||
|
SimplePaymentDto.from(
|
||||||
|
Payment.from(
|
||||||
|
CreatePaymentDto.of(1L, "토르", KAKAO_PAY, COMPLETED, "004-323-77544", 30_000)))
|
||||||
|
);
|
||||||
|
|
||||||
|
when(userRepository.findByEmailAndIsDeletedFalse("ticketing@gmail.com")).thenReturn(Optional.of(user));
|
||||||
|
when(paymentClient.getSimplePayments(any())).thenReturn(SimplePaymentsResponse.from(1L, paymentDtos));
|
||||||
|
|
||||||
|
// when
|
||||||
|
SimplePaymentDetailsResponse paymentDetails = userService.findSimplePaymentDetails("ticketing@gmail.com");
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertAll(
|
||||||
|
() -> assertThat(paymentDetails.getEmail()).isEqualTo("ticketing@gmail.com")
|
||||||
|
, () -> assertThat(paymentDetails.getPayments()).hasSize(2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user