Skip to content

Commit

Permalink
Merge pull request #113 from c0smosaur/refactor/#60-reservation-valid…
Browse files Browse the repository at this point in the history
…ator

[REFACTOR] Refactor/#60 reservation validator
  • Loading branch information
c0smosaur authored Jun 10, 2024
2 parents 637f362 + 93564f4 commit 69237bb
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public enum BaseResponseStatus {
INVALID_AUTHCODE(false, BAD_REQUEST.value(), "인증에 실패했습니다."),
INVALID_RESERVATION_DATE(false, BAD_REQUEST.value(), "예약 날짜가 옳지 않습니다."),

DUPLICATE_RESERVATION(false, BAD_REQUEST.value(), "중복된 예약입니다."),
CONCURRENCY_CONFLICT(false, BAD_REQUEST.value(), "예약 정보가 수정되었습니다. 새로고침 후 다시 시도해주세요."),

INVALID_REQUEST(false, BAD_REQUEST.value(), "잘못된 요청입니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ public BaseResponse<MembershipReservationListResponse> getMembershipReservations
// 기업 멤버십 예약 추가
@PostMapping("/my-membership/{membershipId}")
public BaseResponse<MembershipReservationListResponse> addReservation(
@AuthenticationPrincipal MemberDetails memberDetails,
@PathVariable Long membershipId,
@RequestBody List<ReservationRequest> requests){
return BaseResponse.response(
companyMembershipReservationService.addCompanyReservations(
membershipId, requests));
memberDetails.getMember(), membershipId, requests));
}

// 기업 멤버십 예약 개별 조회
Expand All @@ -73,11 +74,13 @@ public BaseResponse<ReservationResponse> getReservation(
// 기업 멤버십 예약 개별 수정
@PutMapping("/my-membership/{membershipId}/reservation/{reservationId}")
public BaseResponse<ReservationResponse> updateReservation(
@AuthenticationPrincipal MemberDetails memberDetails,
@PathVariable Long membershipId,
@PathVariable Long reservationId,
@RequestBody ReservationRequest request){
return BaseResponse.response(
companyMembershipReservationService.updateReservation(request, reservationId, membershipId));
companyMembershipReservationService.updateReservation(
memberDetails.getMember(), request, reservationId, membershipId));
}

// 기업 멤버십 예약 삭제
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public BaseResponse<ReservationResponse> updateReservation(

return BaseResponse.response(
individualMembershipReservationService.updateReservation(
request,reservationId, membershipId));
memberDetails.getMember(), request,reservationId, membershipId));
}

// 사용자 예약 삭제
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.core.linkup.reservation.reservation.entity.Reservation;
import org.springframework.data.jpa.repository.JpaRepository;

import java.time.LocalDateTime;
import java.util.List;

public interface ReservationRepository extends JpaRepository<Reservation, Long>
Expand All @@ -13,4 +14,6 @@ public interface ReservationRepository extends JpaRepository<Reservation, Long>
default Reservation findFirstById(Long id){
return findById(id).orElseThrow(() -> new BaseException(BaseResponseStatus.DOES_NOT_EXIST));
}

Boolean existsByIdAndStartDateAndEndDate(Long seatId, LocalDateTime startDate, LocalDateTime endDate);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

Expand All @@ -33,6 +34,7 @@ public class CompanyMembershipReservationService {

private final CompanyMembershipService companyMembershipService;
private final ReservationService reservationService;
private final ReservationValidationService reservationValidationService;

private final ReservationConverter reservationConverter;
private final CompanyMembershipConverter companyMembershipConverter;
Expand Down Expand Up @@ -79,14 +81,24 @@ public MembershipReservationListResponse getReservationsForCompanyMembership(Mem
public ReservationResponse getReservationForCompanyMembership(
Member member, Long membershipId, Long reservationId){
CompanyMembership companyMembership = companyMembershipRepository.findFirstById(membershipId);
// 사용자 검증
reservationValidationService.validateMember(member, companyMembership);
return reservationService.getReservationResponseForMembership(member, companyMembership, reservationId);
}

// 기업 멤버십 예약 추가 생성
public MembershipReservationListResponse addCompanyReservations(
Long membershipId, List<ReservationRequest> requests){
Member member, Long membershipId, List<ReservationRequest> requests){
CompanyMembership companyMembership =
companyMembershipRepository.findFirstById(membershipId);

// 사용자 검증
reservationValidationService.validateMember(member, companyMembership);
for (ReservationRequest request : requests) {
// 중복 예약, 날짜 검증
reservationValidationService.validateDateAndDuplicateReservation(request);
}

List<ReservationResponse> reservationResponses =
reservationService.createReservationResponses(requests, companyMembership);
return reservationConverter.toMembershipReservationListResponse(
Expand All @@ -95,19 +107,26 @@ public MembershipReservationListResponse addCompanyReservations(
}

// (수정) 기업 멤버십 지정석 수정
public ReservationResponse updateReservation(ReservationRequest request,
Long reservationId,
Long membershipId) {
public ReservationResponse updateReservation(Member member,
ReservationRequest request,
Long reservationId,
Long membershipId) {

Reservation reservation = reservationRepository.findFirstById(reservationId);
CompanyMembership companyMembership = companyMembershipRepository.findFirstById(membershipId);

// 사용자 검증
reservationValidationService.validateMember(member, companyMembership);
// 중복 예약, 날짜 검증
reservationValidationService.validateDateAndDuplicateReservation(request);

return reservationService.updateReservationByType(request, reservation, companyMembership);
}

// (삭제) 개별 예약 삭제
public boolean deleteReservationForCompanyMembership(Member member, Long membershipId, Long reservationId) {
Reservation reservation = reservationRepository.findFirstById(reservationId);
// 사용자 검증
if (member.getCompanyMembershipId().equals(membershipId)){
reservation.setStatus(ReservationStatus.CANCELED);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -49,7 +50,16 @@ public class IndividualMembershipReservationService {
@Transactional
public MembershipReservationListResponse registerIndividualMembership(
IndividualMembershipRegistrationRequest requests, Member member, Long officeId) {

// 사용자 검증
// 중복 예약, 날짜 검증
List<ReservationRequest> reservationRequests = requests.getReservations();
for (ReservationRequest request : reservationRequests) {
// 중복 예약, 날짜 검증
reservationValidationService.validateDateAndDuplicateReservation(request);
}
reservationValidationService.validateOfficeLocation(requests, officeId);

IndividualMembership membership =
individualMembershipService.saveIndividualMembership(officeId, requests.getMembership(), member);
List<ReservationResponse> reservationResponses =
Expand All @@ -63,7 +73,17 @@ public MembershipReservationListResponse registerIndividualMembership(
@Transactional
public MembershipReservationListResponse addIndividualReservations(
Member member, List<ReservationRequest> requests, Long membershipId){

IndividualMembership individualMembership = individualMembershipRepository.findFirstById(membershipId);

// 사용자 검증
// 중복 예약, 날짜 검증
reservationValidationService.validateMember(member, individualMembership);
for (ReservationRequest request : requests) {
// 중복 예약, 날짜 검증
reservationValidationService.validateDateAndDuplicateReservation(request);
}

List<ReservationResponse> reservationResponses =
createReservationResponses(requests, individualMembership);
return reservationConverter.toMembershipReservationListResponse(
Expand Down Expand Up @@ -123,29 +143,40 @@ public List<ReservationResponse> getReservationsForIndividualMembership(
Member member, Long individualMembershipId){
IndividualMembership individualMembership =
individualMembershipRepository.findFirstById(individualMembershipId);

// 사용자 검증
reservationValidationService.validateMember(member, individualMembership);
return reservationService.getReservationResponsesWithMembership(member, individualMembership);
}

// (조회) 개별 예약 조회
// null이면 404
public ReservationResponse getReservationForIndividualMembership(
Member member, Long membershipId, Long reservationId){
if (reservationRepository.existsById(reservationId)){
IndividualMembership individualMembership =
individualMembershipRepository.findFirstById(membershipId);

reservationValidationService.validateMember(member, individualMembership);
return reservationService.getReservationResponseForMembership(member, individualMembership, reservationId);
} else {
throw new BaseException(BaseResponseStatus.DOES_NOT_EXIST);
}
}

// (수정) 개인 멤버십 지정석 수정
public ReservationResponse updateReservation(ReservationRequest request,
public ReservationResponse updateReservation(Member member,
ReservationRequest request,
Long reservationId,
Long membershipId) {

Reservation reservation = reservationRepository.findFirstById(reservationId);
IndividualMembership individualMembership = individualMembershipRepository.findFirstById(membershipId);

// 검증
reservationValidationService.validateMember(member, individualMembership);
// 중복 예약, 날짜 검증
reservationValidationService.validateDateAndDuplicateReservation(request);

return reservationService.updateReservationByType(request, reservation, individualMembership);

}
Expand All @@ -156,6 +187,10 @@ public boolean deleteReservationForIndividualMembership(Member member, Long memb
Reservation reservation = reservationRepository.findFirstById(reservationId);
IndividualMembership individualMembership =
individualMembershipRepository.findFirstById(membershipId);

// 사용자 검증
reservationValidationService.validateMember(member, individualMembership);

if (individualMembership.getMemberId().equals(member.getId())){
reservation.setStatus(ReservationStatus.CANCELED);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

import com.core.linkup.common.exception.BaseException;
import com.core.linkup.common.response.BaseResponseStatus;
import com.core.linkup.member.entity.Member;
import com.core.linkup.office.entity.OfficeBuilding;
import com.core.linkup.office.repository.OfficeRepository;
import com.core.linkup.reservation.membership.company.entity.CompanyMembership;
import com.core.linkup.reservation.membership.individual.entity.IndividualMembership;
import com.core.linkup.reservation.membership.individual.entity.enums.MembershipType;
import com.core.linkup.reservation.reservation.converter.ReservationConverter;
import com.core.linkup.reservation.reservation.entity.enums.ReservationType;
import com.core.linkup.reservation.reservation.repository.ReservationRepository;
import com.core.linkup.reservation.reservation.request.IndividualMembershipRegistrationRequest;
import com.core.linkup.reservation.reservation.request.ReservationRequest;
Expand All @@ -24,6 +29,7 @@ public class ReservationValidationService {

private final OfficeRepository officeRepository;
private final ReservationConverter reservationConverter;
private final ReservationRepository reservationRepository;

// (검증) 개인 멤버십 요청의 지점과 전달받은 지점 일치하는지 검증
public void validateOfficeLocation(IndividualMembershipRegistrationRequest requests, Long officeId) {
Expand All @@ -33,6 +39,47 @@ public void validateOfficeLocation(IndividualMembershipRegistrationRequest reque
}
}

public void validateDateAndDuplicateReservation(
ReservationRequest request){
validateDuplicateReservation(request);
validateReservationDate(request);
}

// 사용자 검증(개인 멤버십)
public void validateMember(Member member, IndividualMembership membership){
if (!member.getId().equals(membership.getMemberId())){
throw new BaseException(BaseResponseStatus.INVALID_REQUEST);
}
}

// 사용자 검증(기업 멤버십)
public void validateMember(Member member, CompanyMembership membership){
if (!member.getCompanyMembershipId().equals(membership.getId())){
throw new BaseException(BaseResponseStatus.INVALID_REQUEST);
}
}

// 사용자 검증(기업 멤버십, 기업 멤버십 id로)
public void validateMember(Member member, Long companyMembershipId){
if (!member.getCompanyMembershipId().equals(companyMembershipId)){
throw new BaseException(BaseResponseStatus.INVALID_REQUEST);
}
}

// 중복 예약 검증
public void validateDuplicateReservation(ReservationRequest request){
// startDate, startTime, endDate, endTime 찾아서 가져옴
List<LocalDateTime> dates = reservationConverter.getLocalDateTime(request);
LocalDateTime startDate = dates.get(0);
LocalDateTime endDate = dates.get(1);

// 해당 좌석에 해당 날짜로 예약이 있는지 파악
// 있으면 예외
if (reservationRepository.existsByIdAndStartDateAndEndDate(request.getSeatId(), startDate, endDate)){
throw new BaseException(BaseResponseStatus.DUPLICATE_RESERVATION);
}
}

// 예약 날짜 검증
public void validateReservationDate(ReservationRequest request){
// 검증 통과 x 사례
Expand All @@ -59,11 +106,65 @@ public boolean validateSpaceReservationTime(ReservationRequest request){
return duration.toHours() <= 2;
}

// 개인 멤버십 생성
// 당일권은 공간 예약 최대 3개, 자율좌석 1개
// 30일 패스는 지정석 1개, 자율좌석 5개까지, 공간예약 ?
// public boolean validateMembershipAndReservationType(IndividualMembershipRequest request){
//
// }
// 30일 패스는 지정석 1개, 자율좌석 5개까지
public void validateIndividualMembershipAndReservationType(IndividualMembershipRegistrationRequest request){
int designated = 0;
int temporary = 0;
int space = 0;

MembershipType membershipType = MembershipType.fromKor(request.getMembership().getType());
List<ReservationRequest> reservations = request.getReservations();
for (ReservationRequest reservation : reservations) {
ReservationType reservationType = ReservationType.fromKor(reservation.getType());

switch (reservationType){
case TEMPORARY_SEAT -> temporary += 1;
case DESIGNATED_SEAT -> designated += 1;
case SPACE -> space += 1;
default -> throw new BaseException(BaseResponseStatus.INVALID_REQUEST);
}
}

if (membershipType.equals(MembershipType.ONE_DAY_PASS)){
// 1일 패스
if (designated > 0 || temporary < 0 || temporary > 5 || space > 3){
throw new BaseException(BaseResponseStatus.INVALID_REQUEST);
}
} else {
// 30일 패스
if (designated < 0 || designated > 1){
throw new BaseException(BaseResponseStatus.INVALID_REQUEST);
}
}
}

// 예약 추가 시
public void validateReservationRequests(
List<ReservationRequest> requests, MembershipType membershipType){
int companyDesignated = 0;
int designated = 0;
int temporary = 0;
int space = 0;

for (ReservationRequest request : requests) {
ReservationType reservationType = ReservationType.fromKor(request.getType());

switch (reservationType){
case COMPANY_DESIGNATED_SEAT -> companyDesignated += 1;
case TEMPORARY_SEAT -> temporary += 1;
case DESIGNATED_SEAT -> designated += 1;
case SPACE -> space += 1;
default -> throw new BaseException(BaseResponseStatus.INVALID_REQUEST);
}
}

if (membershipType.equals(MembershipType.ONE_DAY_PASS)){

}

}


// 공간예약 가격 검증
Expand Down

0 comments on commit 69237bb

Please sign in to comment.