diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/ReserveApiController.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/ReserveApiController.java
similarity index 81%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/ReserveApiController.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/ReserveApiController.java
index 2885120..c0dc310 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/ReserveApiController.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/ReserveApiController.java
@@ -1,29 +1,32 @@
-package org.egovframe.cloud.reservechecksevice.api.reserve;
+package org.egovframe.cloud.reservechecksevice.api;
import java.time.LocalDate;
-
+import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
-import org.egovframe.cloud.common.dto.RequestDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.*;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.Category;
-import org.egovframe.cloud.reservechecksevice.service.reserve.ReserveService;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveCancelRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveListResponseDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveResponseDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveSaveRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveUpdateRequestDto;
+import org.egovframe.cloud.reservechecksevice.service.ReserveService;
import org.springframework.core.env.Environment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.ReactiveSecurityContextHolder;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.web.bind.annotation.*;
-import reactor.core.publisher.Flux;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
-import javax.validation.Valid;
-
/**
- * org.egovframe.cloud.reservechecksevice.api.reserve.ReserveApiController
+ * org.egovframe.cloud.reservechecksevice.api.ReserveApiController
*
* 예약 확인 rest controller class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveCancelRequestDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveCancelRequestDto.java
similarity index 83%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveCancelRequestDto.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveCancelRequestDto.java
index cdc0a0a..8afc3da 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveCancelRequestDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveCancelRequestDto.java
@@ -1,14 +1,13 @@
-package org.egovframe.cloud.reservechecksevice.api.reserve.dto;
+package org.egovframe.cloud.reservechecksevice.api.dto;
import javax.validation.constraints.NotBlank;
-
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
- * org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveCancelRequestDto
+ * org.egovframe.cloud.reservechecksevice.api.dto.ReserveCancelRequestDto
*
* 예약 취소 요청 dto class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveListResponseDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveListResponseDto.java
similarity index 88%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveListResponseDto.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveListResponseDto.java
index 0d6577f..3a13136 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveListResponseDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveListResponseDto.java
@@ -1,15 +1,14 @@
-package org.egovframe.cloud.reservechecksevice.api.reserve.dto;
+package org.egovframe.cloud.reservechecksevice.api.dto;
+import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.Reserve;
-
-import java.time.LocalDateTime;
+import org.egovframe.cloud.reservechecksevice.domain.Reserve;
/**
- * org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveListResponseDto
+ * org.egovframe.cloud.reservechecksevice.api.dto.ReserveListResponseDto
*
* 예약 목록 응답 dto class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveRequestDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveRequestDto.java
similarity index 81%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveRequestDto.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveRequestDto.java
index 9c9e361..de9f060 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveRequestDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveRequestDto.java
@@ -1,11 +1,11 @@
-package org.egovframe.cloud.reservechecksevice.api.reserve.dto;
+package org.egovframe.cloud.reservechecksevice.api.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.egovframe.cloud.common.dto.RequestDto;
/**
- * org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveRequestDto
+ * org.egovframe.cloud.reservechecksevice.api.dto.ReserveRequestDto
*
* 얘약 목록 요청 dto class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveResponseDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveResponseDto.java
similarity index 89%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveResponseDto.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveResponseDto.java
index 52c73cf..7d7ec85 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveResponseDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveResponseDto.java
@@ -1,17 +1,15 @@
-package org.egovframe.cloud.reservechecksevice.api.reserve.dto;
+package org.egovframe.cloud.reservechecksevice.api.dto;
+import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.reservechecksevice.client.dto.ReserveItemRelationResponseDto;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.Reserve;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
+import org.egovframe.cloud.reservechecksevice.domain.Reserve;
/**
- * org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveResponseDto
+ * org.egovframe.cloud.reservechecksevice.api.dto.ReserveResponseDto
*
* 예약 확인(신청) 응답 dto class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveSaveRequestDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveSaveRequestDto.java
similarity index 89%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveSaveRequestDto.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveSaveRequestDto.java
index 7eaa3b6..54dafeb 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveSaveRequestDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveSaveRequestDto.java
@@ -1,20 +1,18 @@
-package org.egovframe.cloud.reservechecksevice.api.reserve.dto;
+package org.egovframe.cloud.reservechecksevice.api.dto;
+import java.time.LocalDateTime;
+import java.util.UUID;
+import javax.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
-import lombok.With;
-
-import org.egovframe.cloud.reservechecksevice.domain.reserve.Reserve;
+import org.egovframe.cloud.reservechecksevice.domain.Reserve;
import org.egovframe.cloud.reservechecksevice.validator.annotation.ReserveSaveValid;
-import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
-
/**
- * org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveSaveRequestDto
+ * org.egovframe.cloud.reservechecksevice.api.dto.ReserveSaveRequestDto
*
* 예약 신청 요청 dto class
*
@@ -77,6 +75,11 @@ public class ReserveSaveRequestDto {
this.userEmail = userEmail;
}
+ public Reserve createNewReserve() {
+ this.reserveId = String.valueOf(UUID.randomUUID());
+ return toEntity();
+ }
+
public Reserve toEntity() {
Reserve reserve = Reserve.builder()
.reserveId(this.reserveId)
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveUpdateRequestDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveUpdateRequestDto.java
similarity index 93%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveUpdateRequestDto.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveUpdateRequestDto.java
index 50efc06..160ffd1 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/reserve/dto/ReserveUpdateRequestDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/api/dto/ReserveUpdateRequestDto.java
@@ -1,16 +1,15 @@
-package org.egovframe.cloud.reservechecksevice.api.reserve.dto;
+package org.egovframe.cloud.reservechecksevice.api.dto;
+import java.time.LocalDateTime;
+import javax.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.reservechecksevice.validator.annotation.ReserveSaveValid;
-import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
-
/**
- * org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveUpdateRequestDto
+ * org.egovframe.cloud.reservechecksevice.api.dto.ReserveUpdateRequestDto
*
* 예약 신청 정보 수정 요청 dto class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/ReserveItemServiceClient.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/ReserveItemServiceClient.java
index 2bbb0b9..c81948e 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/ReserveItemServiceClient.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/ReserveItemServiceClient.java
@@ -6,7 +6,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
-
import reactivefeign.spring.config.ReactiveFeignClient;
import reactor.core.publisher.Mono;
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/UserServiceClient.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/UserServiceClient.java
index 26346fa..35cb848 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/UserServiceClient.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/UserServiceClient.java
@@ -3,7 +3,6 @@ package org.egovframe.cloud.reservechecksevice.client;
import org.egovframe.cloud.reservechecksevice.client.dto.UserResponseDto;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
-
import reactivefeign.spring.config.ReactiveFeignClient;
import reactor.core.publisher.Mono;
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemRelationResponseDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemRelationResponseDto.java
index e951eb9..7afd96a 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemRelationResponseDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemRelationResponseDto.java
@@ -1,16 +1,14 @@
package org.egovframe.cloud.reservechecksevice.client.dto;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
-
+import org.egovframe.cloud.reservechecksevice.domain.ReserveItem;
import org.egovframe.cloud.reservechecksevice.domain.location.Location;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveItem;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
/**
* org.egovframe.cloud.reservechecksevice.client.dto.ReserveItemRelationResponseDto
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemResponseDto.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemResponseDto.java
index b68c3a7..f1df3c2 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemResponseDto.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/client/dto/ReserveItemResponseDto.java
@@ -1,13 +1,12 @@
package org.egovframe.cloud.reservechecksevice.client.dto;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveItem;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
+import org.egovframe.cloud.reservechecksevice.domain.ReserveItem;
/**
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemResponseDto
@@ -30,6 +29,8 @@ import java.time.LocalDateTime;
@NoArgsConstructor
@ToString
public class ReserveItemResponseDto {
+ private static final int MIN_QTY = 0;
+
private Long reserveItemId; // 예약 물품 id
private String reserveItemName; //예약 물품 명
private Long locationId;
@@ -90,4 +91,16 @@ public class ReserveItemResponseDto {
this.managerName = reserveItem.getManagerName();
this.managerContact = reserveItem.getManagerContact();
}
+
+ public boolean isPossibleQty(Integer max, Integer reserveQty) {
+ return (totalQty - max) >= reserveQty;
+ }
+
+ public boolean isPositiveInventory() {
+ return inventoryQty > MIN_QTY;
+ }
+
+ public boolean isPossibleInventoryQty(Integer reserveQty) {
+ return inventoryQty >= reserveQty;
+ }
}
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/config/Resilience4JConfig.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/config/Resilience4JConfig.java
index 89881a7..cb35abb 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/config/Resilience4JConfig.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/config/Resilience4JConfig.java
@@ -1,12 +1,10 @@
package org.egovframe.cloud.reservechecksevice.config;
-import java.time.Duration;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
+import java.time.Duration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
/**
* org.egovframe.cloud.portalservice.config.Resilience4JConfig
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/Category.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/Category.java
similarity index 84%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/Category.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/Category.java
index 525f7ac..eabbbd4 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/Category.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/Category.java
@@ -1,10 +1,10 @@
-package org.egovframe.cloud.reservechecksevice.domain.reserve;
+package org.egovframe.cloud.reservechecksevice.domain;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
- * org.egovframe.cloud.reservechecksevice.domain.reserve.Category
+ * org.egovframe.cloud.reservechecksevice.domain.Category
*
* 예약 유형 enum class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/Reserve.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/Reserve.java
similarity index 83%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/Reserve.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/Reserve.java
index c258e9a..4deb7ef 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/Reserve.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/Reserve.java
@@ -1,21 +1,23 @@
-package org.egovframe.cloud.reservechecksevice.domain.reserve;
+package org.egovframe.cloud.reservechecksevice.domain;
-import lombok.*;
+import java.time.LocalDateTime;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.With;
+import org.egovframe.cloud.common.exception.BusinessMessageException;
import org.egovframe.cloud.reactive.domain.BaseEntity;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveUpdateRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveUpdateRequestDto;
import org.egovframe.cloud.reservechecksevice.client.dto.UserResponseDto;
-import org.egovframe.cloud.reservechecksevice.domain.location.Location;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
-import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Size;
-import java.time.LocalDateTime;
-
/**
- * org.egovframe.cloud.reservechecksevice.domain.reserve.Reserve
+ * org.egovframe.cloud.reservechecksevice.domain.Reserve
*
* 예약 도메인 클래스
*
@@ -112,6 +114,10 @@ public class Reserve extends BaseEntity {
this.userEmail = userEmail;
}
+ public boolean isReserveUser(String userId) {
+ return this.userId.equals(userId);
+ }
+
/**
* 물품 정보 세팅
*
@@ -203,4 +209,26 @@ public class Reserve extends BaseEntity {
return this;
}
+
+ public boolean isDone() {
+ return ReserveStatus.DONE.isEquals(this.reserveStatusId);
+ }
+
+ public Reserve updateStatusCancel(String reason, String errorMessage) {
+ if (isDone()) {
+ throw new BusinessMessageException(errorMessage);
+ }
+
+ this.reserveStatusId = ReserveStatus.CANCEL.getKey();
+ this.reasonCancelContent = reason;
+ return this;
+ }
+
+ public boolean isEducation() {
+ return Category.EDUCATION.isEquals(this.getCategoryId());
+ }
+
+ public boolean isRequest() {
+ return ReserveStatus.REQUEST.isEquals(this.reserveStatusId);
+ }
}
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveItem.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveItem.java
similarity index 98%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveItem.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveItem.java
index fe43fc1..dcbcc26 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveItem.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveItem.java
@@ -1,6 +1,10 @@
-package org.egovframe.cloud.reservechecksevice.domain.reserve;
+package org.egovframe.cloud.reservechecksevice.domain;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -10,12 +14,6 @@ import org.egovframe.cloud.reservechecksevice.domain.location.Location;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.relational.core.mapping.Column;
-import org.springframework.data.relational.core.mapping.Table;
-
-import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Size;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
/**
* org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepository.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepository.java
similarity index 79%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepository.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepository.java
index 837aafa..23ce968 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepository.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepository.java
@@ -1,9 +1,9 @@
-package org.egovframe.cloud.reservechecksevice.domain.reserve;
+package org.egovframe.cloud.reservechecksevice.domain;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
/**
- * org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveRepository
+ * org.egovframe.cloud.reservechecksevice.domain.ReserveRepository
*
* 예약 도메인 Repository interface
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepositoryCustom.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepositoryCustom.java
similarity index 84%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepositoryCustom.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepositoryCustom.java
index 787dff9..192e058 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepositoryCustom.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepositoryCustom.java
@@ -1,15 +1,13 @@
-package org.egovframe.cloud.reservechecksevice.domain.reserve;
+package org.egovframe.cloud.reservechecksevice.domain;
-import org.egovframe.cloud.common.dto.RequestDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveRequestDto;
+import java.time.LocalDateTime;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveRequestDto;
import org.springframework.data.domain.Pageable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.time.LocalDateTime;
-
/**
- * org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveRepositoryCustom
+ * org.egovframe.cloud.reservechecksevice.domain.ReserveRepositoryCustom
*
* 예약 도메인 custom Repository interface
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepositoryImpl.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepositoryImpl.java
similarity index 97%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepositoryImpl.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepositoryImpl.java
index 21fc308..bece766 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveRepositoryImpl.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveRepositoryImpl.java
@@ -1,14 +1,15 @@
-package org.egovframe.cloud.reservechecksevice.domain.reserve;
+package org.egovframe.cloud.reservechecksevice.domain;
-import static org.springframework.data.relational.core.query.Criteria.*;
+import static org.springframework.data.relational.core.query.Criteria.where;
-import java.time.LocalDate;
+import io.github.resilience4j.circuitbreaker.CircuitBreaker;
+import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
+import io.github.resilience4j.reactor.circuitbreaker.operator.CircuitBreakerOperator;
import java.time.LocalDateTime;
-import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
-
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveRequestDto;
+import lombok.RequiredArgsConstructor;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveRequestDto;
import org.egovframe.cloud.reservechecksevice.client.ReserveItemServiceClient;
import org.egovframe.cloud.reservechecksevice.client.UserServiceClient;
import org.egovframe.cloud.reservechecksevice.client.dto.UserResponseDto;
@@ -18,16 +19,11 @@ import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.util.StringUtils;
-
-import io.github.resilience4j.circuitbreaker.CircuitBreaker;
-import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
-import io.github.resilience4j.reactor.circuitbreaker.operator.CircuitBreakerOperator;
-import lombok.RequiredArgsConstructor;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
- * org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveRepositoryImpl
+ * org.egovframe.cloud.reservechecksevice.domain.ReserveRepositoryImpl
*
* 예약 도메인 custom repository 구현 클래스
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveStatus.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveStatus.java
similarity index 85%
rename from backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveStatus.java
rename to backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveStatus.java
index 9568c96..52a24a0 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/reserve/ReserveStatus.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveStatus.java
@@ -1,10 +1,10 @@
-package org.egovframe.cloud.reservechecksevice.domain.reserve;
+package org.egovframe.cloud.reservechecksevice.domain;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
- * org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveStatus
+ * org.egovframe.cloud.reservechecksevice.domain.ReserveStatus
*
* 예약 상태 enum class
*
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveValidator.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveValidator.java
new file mode 100644
index 0000000..b65d98a
--- /dev/null
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/ReserveValidator.java
@@ -0,0 +1,259 @@
+package org.egovframe.cloud.reservechecksevice.domain;
+
+import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
+import io.github.resilience4j.reactor.circuitbreaker.operator.CircuitBreakerOperator;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.stream.IntStream;
+import javax.annotation.Resource;
+import lombok.RequiredArgsConstructor;
+import org.egovframe.cloud.common.exception.BusinessMessageException;
+import org.egovframe.cloud.common.util.MessageUtil;
+import org.egovframe.cloud.reservechecksevice.client.ReserveItemServiceClient;
+import org.egovframe.cloud.reservechecksevice.client.dto.ReserveItemResponseDto;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+@Component
+@RequiredArgsConstructor
+public class ReserveValidator {
+ private static final String CHECK_RESERVE_MEANS = "realtime";
+ private static final String RESERVE_ITEM_CIRCUIT_BREAKER_NAME = "reserve-item";
+
+ @Resource(
+ name = "messageUtil"
+ )
+ protected MessageUtil messageUtil;
+
+ private final ReserveRepository reserveRepository;
+ private final ReserveItemServiceClient reserveItemServiceClient;
+ private final CircuitBreakerRegistry circuitBreakerRegistry;
+
+ /**
+ * 공간 예약 시 예약 날짜에 다른 예약이 있는지 체크
+ *
+ * @param reserveItem
+ * @param reserve
+ * @return
+ */
+ public Mono checkSpace(ReserveItemResponseDto reserveItem, Reserve reserve) {
+ return this.checkReserveDate(reserveItem, reserve)
+ .flatMap(isValid -> reserveRepository.findAllByReserveDateWithoutSelfCount(
+ reserve.getReserveId(),
+ reserveItem.getReserveItemId(),
+ reserve.getReserveStartDate(),
+ reserve.getReserveEndDate())
+ .flatMap(count -> {
+ if (count > 0) {
+ //"해당 날짜에는 예약할 수 없습니다."
+ return Mono.error(new BusinessMessageException(getMessage("valid.reserve_date")));
+ }
+ return Mono.just(reserve);
+ })
+ );
+ }
+
+ /**
+ * 장비 예약 시 예약 날짜에 예약 가능한 재고 체크
+ *
+ * @param reserveItem
+ * @param reserve
+ * @return
+ */
+ public Mono checkEquipment(ReserveItemResponseDto reserveItem, Reserve reserve) {
+ return this.checkReserveDate(reserveItem, reserve)
+ .flatMap(entity -> this.getMaxByReserveDateWithoutSelf(
+ entity.getReserveId(),
+ reserveItem.getReserveItemId(),
+ entity.getReserveStartDate(),
+ entity.getReserveEndDate())
+ .flatMap(max -> Mono.just((reserveItem.isPossibleQty(max, reserve.getReserveQty()))))
+ .flatMap(isValid -> {
+ if (isValid) {
+ return Mono.just(reserve);
+ }
+ //해당 날짜에 예약할 수 있는 재고수량이 없습니다.
+ return Mono.error(new BusinessMessageException(getMessage("valid.reserve_count")));
+ })
+ );
+ }
+
+ /**
+ * 교육 예약 시 재고 체크
+ *
+ * @param reserveItem
+ * @param reserve
+ * @return
+ */
+ public Mono checkEducation(ReserveItemResponseDto reserveItem, Reserve reserve) {
+ return Mono.just(reserveItem)
+ .flatMap(reserveItemResponseDto -> {
+ LocalDateTime now = LocalDateTime.now();
+ LocalDateTime startDate = reserveItemResponseDto.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
+ reserveItemResponseDto.getRequestStartDate() : reserveItemResponseDto.getOperationStartDate();
+ LocalDateTime endDate = reserveItemResponseDto.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
+ reserveItemResponseDto.getRequestEndDate() : reserveItemResponseDto.getOperationEndDate();
+
+ if (!(now.isAfter(startDate) && now.isBefore(endDate))) {
+ //해당 날짜에는 예약할 수 없습니다.
+ return Mono.error(new BusinessMessageException(getMessage("valid.reserve_date")));
+ }
+
+ if (!reserveItemResponseDto.isPositiveInventory()) {
+ //"예약이 마감되었습니다."
+ return Mono.error(new BusinessMessageException(getMessage("valid.reserve_close")));
+ }
+
+ if (reserveItemResponseDto.isPossibleInventoryQty(reserve.getReserveQty())) {
+ //예약가능한 인원이 부족합니다. (남은 인원 : {0})
+ return Mono.error(new BusinessMessageException(getMessage("valid.reserve_number_of_people", new Object[]{reserveItemResponseDto.getInventoryQty()})));
+ }
+ return Mono.just(reserve);
+ });
+ }
+
+ /**
+ * 예약물품에 대해 날짜별 예약된 수량 max 조회
+ *
+ * @param reserveItemId
+ * @param startDate
+ * @param endDate
+ * @return
+ */
+ public Mono getMaxByReserveDate(Long reserveItemId, LocalDateTime startDate, LocalDateTime endDate) {
+ Flux reserveFlux = reserveRepository.findAllByReserveDate(reserveItemId, startDate, endDate)
+ .switchIfEmpty(Flux.empty());
+ return countMax(reserveFlux, startDate, endDate);
+ }
+
+ /**
+ * 예약 물품 재고 및 예약 일자 체크
+ *
+ * @param reserve
+ * @return
+ */
+ public Mono checkReserveItems(Reserve reserve) {
+ return reserveItemServiceClient.findById(reserve.getReserveItemId())
+ .transform(CircuitBreakerOperator
+ .of(circuitBreakerRegistry.circuitBreaker(RESERVE_ITEM_CIRCUIT_BREAKER_NAME)))
+ .onErrorResume(throwable -> Mono.empty())
+ .flatMap(reserveItemResponseDto -> {
+ // validation check
+ if (Category.SPACE.isEquals(reserveItemResponseDto.getCategoryId())) {
+ return checkSpace(reserveItemResponseDto, reserve);
+ }
+ if (Category.EQUIPMENT.isEquals(reserveItemResponseDto.getCategoryId())) {
+ return checkEquipment(reserveItemResponseDto, reserve);
+ }
+ if (Category.EDUCATION.isEquals(reserveItemResponseDto.getCategoryId())) {
+ return checkEducation(reserveItemResponseDto, reserve);
+ }
+ return Mono.just(reserve);
+ });
+ }
+
+
+ /**
+ * 예약 날짜 validation
+ *
+ * @param reserveItem
+ * @param reserve
+ * @return
+ */
+ private Mono checkReserveDate(ReserveItemResponseDto reserveItem, Reserve reserve) {
+ LocalDateTime startDate = reserveItem.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
+ reserveItem.getRequestStartDate() : reserveItem.getOperationStartDate();
+ LocalDateTime endDate = reserveItem.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
+ reserveItem.getRequestEndDate() : reserveItem.getOperationEndDate();
+
+ if (reserve.getReserveStartDate().isBefore(startDate)) {
+ //{0}이 {1} 보다 빠릅니다. 시작일, 운영/예약 시작일
+ return Mono.error(new BusinessMessageException(getMessage("valid.to_be_fast.format", new Object[]{getMessage("common.start_date"),
+ getMessage("reserve_item.operation")+getMessage("reserve")+" "+getMessage("common.start_date")})));
+ }
+
+ if (reserve.getReserveEndDate().isAfter(endDate)) {
+ //{0}이 {1} 보다 늦습니다. 종료일, 운영/예약 종료일
+ return Mono.error(new BusinessMessageException(getMessage("valid.to_be_slow.format", new Object[]{getMessage("common.end_date"),
+ getMessage("reserve_item.operation")+getMessage("reserve")+" "+getMessage("common.end_date")})));
+ }
+
+ if (reserveItem.getIsPeriod()) {
+ long between = ChronoUnit.DAYS.between(reserve.getReserveStartDate(), reserve.getReserveEndDate());
+ if (reserveItem.getPeriodMaxCount() < between) {
+ //최대 예약 가능 일수보다 예약기간이 깁니다. (최대 예약 가능일 수 : {0})
+ return Mono.error(new BusinessMessageException(getMessage("valid.reserve_period", new Object[]{reserveItem.getPeriodMaxCount()})));
+ }
+ }
+
+ return Mono.just(reserve);
+ }
+
+ /**
+ * 예약물품에 대해 날짜별 예약된 수량 max 조회
+ * 현 예약 건 제외
+ *
+ * @param reserveItemId
+ * @param startDate
+ * @param endDate
+ * @return
+ */
+ private Mono getMaxByReserveDateWithoutSelf(String reserveId, Long reserveItemId, LocalDateTime startDate, LocalDateTime endDate) {
+ Flux reserveFlux = reserveRepository.findAllByReserveDateWithoutSelf(reserveId, reserveItemId, startDate, endDate)
+ .switchIfEmpty(Flux.empty());
+ return countMax(reserveFlux, startDate, endDate);
+ }
+
+ /**
+ * get max
+ *
+ * @param reserveFlux
+ * @param startDate
+ * @param endDate
+ * @return
+ */
+ private Mono countMax(Flux reserveFlux, LocalDateTime startDate, LocalDateTime endDate) {
+ if (reserveFlux.equals(Flux.empty())) {
+ return Mono.just(0);
+ }
+
+ long between = ChronoUnit.DAYS.between(startDate, endDate);
+
+ if (between == 0) {
+ return reserveFlux.map(reserve -> {
+ if (startDate.isAfter(reserve.getReserveStartDate())
+ || startDate.isBefore(reserve.getReserveEndDate())
+ || startDate.isEqual(reserve.getReserveStartDate()) || startDate.isEqual(reserve.getReserveEndDate())) {
+ return reserve.getReserveQty();
+ }
+ return 0;
+ }).reduce(0, (x1, x2) -> x1 + x2);
+ }
+
+ return Flux.fromStream(IntStream.iterate(0, i -> i + 1)
+ .limit(between)
+ .mapToObj(i -> startDate.plusDays(i)))
+ .flatMap(localDateTime ->
+ reserveFlux.map(findReserve -> {
+ if (localDateTime.isAfter(findReserve.getReserveStartDate())
+ || localDateTime.isBefore(findReserve.getReserveEndDate())
+ || localDateTime.isEqual(findReserve.getReserveStartDate()) || localDateTime.isEqual(findReserve.getReserveEndDate())) {
+ return findReserve.getReserveQty();
+ }
+ return 0;
+ }).reduce(0, (x1, x2) -> x1 + x2))
+ .groupBy(integer -> integer)
+ .flatMap(group -> group.reduce((x1,x2) -> x1 > x2?x1:x2))
+ .last(0);
+ }
+
+ private String getMessage(String code) {
+ return this.messageUtil.getMessage(code);
+ }
+
+ private String getMessage(String code, Object[] args) {
+ return this.messageUtil.getMessage(code, args);
+ }
+
+}
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/location/Location.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/location/Location.java
index f9001e8..a100242 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/location/Location.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/domain/location/Location.java
@@ -1,12 +1,13 @@
package org.egovframe.cloud.reservechecksevice.domain.location;
-import lombok.*;
+import javax.validation.constraints.Size;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
import org.egovframe.cloud.reactive.domain.BaseEntity;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
-import org.springframework.data.relational.core.mapping.Table;
-
-import javax.validation.constraints.Size;
/**
* org.egovframe.cloud.reserveitemservice.domain.location.Location
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/service/ReserveService.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/service/ReserveService.java
new file mode 100644
index 0000000..2372e88
--- /dev/null
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/service/ReserveService.java
@@ -0,0 +1,411 @@
+package org.egovframe.cloud.reservechecksevice.service;
+
+import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
+import io.github.resilience4j.reactor.circuitbreaker.operator.CircuitBreakerOperator;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.egovframe.cloud.common.domain.Role;
+import org.egovframe.cloud.common.dto.AttachmentEntityMessage;
+import org.egovframe.cloud.common.exception.BusinessMessageException;
+import org.egovframe.cloud.reactive.service.ReactiveAbstractService;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveCancelRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveListResponseDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveResponseDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveSaveRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveUpdateRequestDto;
+import org.egovframe.cloud.reservechecksevice.client.ReserveItemServiceClient;
+import org.egovframe.cloud.reservechecksevice.domain.Reserve;
+import org.egovframe.cloud.reservechecksevice.domain.ReserveRepository;
+import org.egovframe.cloud.reservechecksevice.domain.ReserveStatus;
+import org.egovframe.cloud.reservechecksevice.domain.ReserveValidator;
+import org.springframework.cloud.stream.function.StreamBridge;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
+import org.springframework.data.domain.Pageable;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.ReactiveSecurityContextHolder;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+/**
+ * org.egovframe.cloud.reservechecksevice.service.ReserveService
+ *
+ * 예약 service 클래스
+ *
+ * @author 표준프레임워크센터 shinmj
+ * @version 1.0
+ * @since 2021/09/15
+ *
+ *
+ * << 개정이력(Modification Information) >>
+ *
+ * 수정일 수정자 수정내용
+ * ---------- -------- ---------------------------
+ * 2021/09/15 shinmj 최초 생성
+ *
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Transactional
+@Service
+public class ReserveService extends ReactiveAbstractService {
+
+ private static final String RESERVE_ITEM_CIRCUIT_BREAKER_NAME = "reserve-item";
+
+ private final ReserveRepository reserveRepository;
+ private final ReserveItemServiceClient reserveItemServiceClient;
+ private final CircuitBreakerRegistry circuitBreakerRegistry;
+ private final StreamBridge streamBridge;
+ private final ReserveValidator validator;
+
+ /**
+ * 목록 조회
+ *
+ * @param requestDto
+ * @param pageable
+ * @return
+ */
+ @Transactional(readOnly = true)
+ public Mono> search(ReserveRequestDto requestDto,
+ Pageable pageable) {
+ return reserveRepository.search(requestDto, pageable)
+ .switchIfEmpty(Flux.empty())
+ .flatMap(this::convertReserveListResponseDto)
+ .collectList()
+ .zipWith(reserveRepository.searchCount(requestDto, pageable))
+ .flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
+ }
+
+ /**
+ * 한건 조회 dto return
+ *
+ * @param reserveId
+ * @return
+ */
+ @Transactional(readOnly = true)
+ public Mono findReserveById(String reserveId) {
+ return reserveRepository.findReserveById(reserveId)
+ .switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveId))
+ .flatMap(this::convertReserveResponseDto);
+ }
+
+ /**
+ * 사용자용 예약 목록 조회 (로그인 사용자의 예약정보만 조회)
+ *
+ * @param userId
+ * @param requestDto
+ * @param pageable
+ * @return
+ */
+ @Transactional(readOnly = true)
+ public Mono> searchForUser(String userId,
+ ReserveRequestDto requestDto, Pageable pageable) {
+ return reserveRepository.searchForUser(requestDto, pageable, userId)
+ .switchIfEmpty(Flux.empty())
+ .flatMap(this::convertReserveListResponseDto)
+ .collectList()
+ .zipWith(reserveRepository.searchCountForUser(requestDto, pageable, userId))
+ .flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
+ }
+
+ /**
+ * 예약 정보 취소
+ *
+ * @param reserveId
+ * @param cancelRequestDto
+ * @return
+ */
+ public Mono cancel(String reserveId, ReserveCancelRequestDto cancelRequestDto) {
+ return getIsAdmin().flatMap(isAdmin -> {
+ if (isAdmin) {
+ return reserveCancel(reserveId, cancelRequestDto);
+ }
+ return findById(reserveId)
+ .zipWith(getUserId())
+ .flatMap(tuple -> {
+ if (tuple.getT1().isReserveUser(tuple.getT2())) {
+ return Mono.just(tuple.getT1());
+ }
+ //해당 예약은 취소할 수 없습니다.
+ return Mono
+ .error(new BusinessMessageException(getMessage("valid.cant_cancel")));
+ })
+ .onErrorResume(throwable -> Mono.error(throwable))
+ .flatMap(reserve -> reserveCancel(reserveId, cancelRequestDto));
+ });
+
+ }
+
+ /**
+ * 예약 상태 취소로 변경
+ *
+ * @param reserveId
+ * @param cancelRequestDto
+ * @return
+ */
+ private Mono reserveCancel(String reserveId, ReserveCancelRequestDto cancelRequestDto) {
+ return findById(reserveId)
+ .map(reserve ->
+ reserve.updateStatusCancel(cancelRequestDto.getReasonCancelContent(), getMessage("valid.cant_cancel_because_done")))
+ .flatMap(reserve -> Mono.just(reserve.conversionReserveQty()))
+ .flatMap(this::updateInventory)
+ .onErrorResume(throwable -> Mono.error(throwable))
+ .flatMap(reserve -> Mono.just(reserve.conversionReserveQty()))
+ .flatMap(reserveRepository::save)
+ .then();
+ }
+
+ /**
+ * 예약 정보 승인
+ *
+ * @param reserveId
+ * @return
+ */
+ public Mono approve(String reserveId) {
+ return getIsAdmin()
+ .flatMap(isAdmin -> {
+ if (isAdmin) {
+ return Mono.just(reserveId);
+ }
+ //관리자만 승인할 수 있습니다.
+ return Mono.error(new BusinessMessageException(getMessage("valid.manager_approve")));
+ })
+ .onErrorResume(Mono::error)
+ .flatMap(this::checkApprove)
+ .onErrorResume(Mono::error)
+ .flatMap(reserveRepository::save).then();
+ }
+
+ /**
+ * 예약 정보 수정
+ *
+ * @param reserveId
+ * @return
+ */
+ public Mono update(String reserveId, ReserveUpdateRequestDto updateRequestDto) {
+ return getIsAdmin().flatMap(isAdmin -> {
+ if (isAdmin) {
+ return updateReserve(reserveId, updateRequestDto);
+ }
+ return updateReserveForUser(reserveId, updateRequestDto);
+ });
+ }
+
+ /**
+ * 관리자 예약 신청 관리자의 경우 실시간이어도 이벤트 스트림 거치지 않고 바로 예약 처리
+ *
+ * @param saveRequestDto
+ * @return
+ */
+ public Mono create(ReserveSaveRequestDto saveRequestDto) {
+ return Mono.just(saveRequestDto)
+ .map(ReserveSaveRequestDto::createNewReserve)
+ .zipWith(getUserId())
+ .flatMap(tuple -> Mono.just(tuple.getT1().setCreatedInfo(LocalDateTime.now(), tuple.getT2())))
+ .flatMap(validator::checkReserveItems)
+ .onErrorResume(Mono::error)
+ .flatMap(this::updateInventory)
+ .onErrorResume(Mono::error)
+ .flatMap(reserveRepository::insert)
+ .flatMap(reserveRepository::loadRelations)
+ .doOnNext(reserve -> sendAttachmentEntityInfo(streamBridge,
+ AttachmentEntityMessage.builder()
+ .attachmentCode(reserve.getAttachmentCode())
+ .entityName(reserve.getClass().getName())
+ .entityId(reserve.getReserveId())
+ .build()))
+ .flatMap(this::convertReserveResponseDto);
+
+
+ }
+
+ /**
+ * 예약 물품별 기간안에 있는 예약된 수량 max 조회
+ *
+ * @param reserveItemId
+ * @param startDate
+ * @param endDate
+ * @return
+ */
+ public Mono countInventory(Long reserveItemId, LocalDateTime startDate,
+ LocalDateTime endDate) {
+ return reserveItemServiceClient.findById(reserveItemId)
+ .transform(CircuitBreakerOperator.of(circuitBreakerRegistry.circuitBreaker(RESERVE_ITEM_CIRCUIT_BREAKER_NAME)))
+ .onErrorResume(throwable -> Mono.empty())
+ .zipWith(validator.getMaxByReserveDate(reserveItemId, startDate, endDate))
+ .flatMap(tuple -> Mono.just(tuple.getT1().getTotalQty() - tuple.getT2()));
+ }
+
+ /**
+ * 승인 전 validate check 및 교육인 경우 재고 업데이트
+ *
+ * @param reserveId
+ * @return
+ */
+ private Mono checkApprove(String reserveId) {
+ return findById(reserveId)
+ .flatMap(validator::checkReserveItems)
+ .onErrorResume(Mono::error)
+ .map(reserve -> reserve.updateStatus(ReserveStatus.APPROVE.getKey()))
+ .flatMap(this::updateInventory);
+ }
+
+ /**
+ * 사용자 예약 수정
+ *
+ * @param reserveId
+ * @param updateRequestDto
+ * @return
+ */
+ private Mono updateReserveForUser(String reserveId,
+ ReserveUpdateRequestDto updateRequestDto) {
+ return findById(reserveId)
+ .zipWith(getUserId())
+ .map(tuple -> {
+ if (!tuple.getT1().isReserveUser(tuple.getT2())) {
+ //"해당 예약은 수정할 수 없습니다."
+ throw new BusinessMessageException(getMessage("valid.reserve_not_update"));
+ }
+
+ if (!tuple.getT1().isRequest()) {
+ //예약 신청 상태인 경우에만 수정 가능합니다.
+ throw new BusinessMessageException(getMessage("valid.reserve_not_update_status"));
+ }
+
+ return tuple.getT1().update(updateRequestDto);
+ })
+ .flatMap(validator::checkReserveItems)
+ .onErrorResume(Mono::error)
+ .flatMap(this::updateInventory)
+ .onErrorResume(Mono::error)
+ .flatMap(reserveRepository::save);
+ }
+
+ /**
+ * 관리자 예약 수정
+ *
+ * @param reserveId
+ * @param updateRequestDto
+ * @return
+ */
+ private Mono updateReserve(String reserveId,
+ ReserveUpdateRequestDto updateRequestDto) {
+ return findById(reserveId)
+ .map(reserve -> {
+ if (!reserve.isRequest()) {
+ //예약 신청 상태인 경우에만 수정 가능합니다.
+ throw new BusinessMessageException(
+ getMessage("valid.reserve_not_update_status"));
+ }
+ return reserve.update(updateRequestDto);
+ })
+ .flatMap(validator::checkReserveItems)
+ .onErrorResume(Mono::error)
+ .flatMap(this::updateInventory)
+ .onErrorResume(Mono::error)
+ .flatMap(reserveRepository::save);
+ }
+
+ /**
+ * 예약 정보 저장 시 재고 변경
+ *
+ * @param reserve
+ * @return
+ */
+ private Mono updateInventory(Reserve reserve) {
+ return Mono.just(reserve)
+ .flatMap(it -> {
+ if (it.isEducation()) {
+ return reserveItemServiceClient
+ .updateInventory(reserve.getReserveItemId(), reserve.getReserveQty())
+ .transform(CircuitBreakerOperator.of(circuitBreakerRegistry
+ .circuitBreaker(RESERVE_ITEM_CIRCUIT_BREAKER_NAME)))
+ .onErrorResume(throwable -> Mono.just(false))
+ .flatMap(isSuccess -> {
+ if (isSuccess) {
+ return Mono.just(reserve);
+ }
+ //재고 업데이트에 실패했습니다.
+ return Mono.error(new BusinessMessageException(getMessage("msg.inventory_failed")));
+ });
+ }
+ return Mono.just(it);
+ });
+ }
+
+ /**
+ * 한건 정보 조회 entity return
+ *
+ * @param reserveId
+ * @return
+ */
+ private Mono findById(String reserveId) {
+ return reserveRepository.findById(reserveId)
+ .switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveId));
+ }
+
+ /**
+ * entity -> dto 변환
+ *
+ * @param reserve
+ * @return
+ */
+ private Mono convertReserveResponseDto(Reserve reserve) {
+ return Mono.just(ReserveResponseDto.builder()
+ .entity(reserve)
+ .build());
+ }
+
+ /**
+ * entity -> 목록 dto 변환
+ *
+ * @param reserve
+ * @return
+ */
+ private Mono convertReserveListResponseDto(Reserve reserve) {
+ return Mono.just(ReserveListResponseDto.builder()
+ .entity(reserve)
+ .build());
+ }
+
+ /**
+ * 현재 로그인 사용자가 관리자인지 체크
+ *
+ * @return
+ */
+ private Mono getIsAdmin() {
+ return ReactiveSecurityContextHolder.getContext()
+ .map(SecurityContext::getAuthentication)
+ .filter(Authentication::isAuthenticated)
+ .map(Authentication::getAuthorities)
+ .map(grantedAuthorities -> {
+ List authorities =
+ new ArrayList<>((Collection extends SimpleGrantedAuthority>) grantedAuthorities);
+ SimpleGrantedAuthority adminRole = new SimpleGrantedAuthority(Role.ADMIN.getKey());
+ return authorities.contains(adminRole);
+ });
+ }
+
+ /**
+ * 현재 로그인 사용자 id
+ *
+ * @return
+ */
+ private Mono getUserId() {
+ return ReactiveSecurityContextHolder.getContext()
+ .map(SecurityContext::getAuthentication)
+ .filter(Authentication::isAuthenticated)
+ .map(Authentication::getPrincipal)
+ .map(String.class::cast);
+ }
+
+}
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/service/reserve/ReserveService.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/service/reserve/ReserveService.java
deleted file mode 100644
index ee29be4..0000000
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/service/reserve/ReserveService.java
+++ /dev/null
@@ -1,640 +0,0 @@
-package org.egovframe.cloud.reservechecksevice.service.reserve;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.IntStream;
-
-import org.egovframe.cloud.common.domain.Role;
-import org.egovframe.cloud.common.dto.AttachmentEntityMessage;
-import org.egovframe.cloud.common.exception.BusinessMessageException;
-import org.egovframe.cloud.reactive.service.ReactiveAbstractService;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveCancelRequestDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveListResponseDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveRequestDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveResponseDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveSaveRequestDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveUpdateRequestDto;
-import org.egovframe.cloud.reservechecksevice.client.ReserveItemServiceClient;
-import org.egovframe.cloud.reservechecksevice.client.dto.ReserveItemResponseDto;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.Category;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.Reserve;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveRepository;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveStatus;
-import org.springframework.cloud.stream.function.StreamBridge;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.Pageable;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.context.ReactiveSecurityContextHolder;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
-import io.github.resilience4j.reactor.circuitbreaker.operator.CircuitBreakerOperator;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-/**
- * org.egovframe.cloud.reservechecksevice.service.reserve.ReserveService
- *
- * 예약 service 클래스
- *
- * @author 표준프레임워크센터 shinmj
- * @version 1.0
- * @since 2021/09/15
- *
- *
- * << 개정이력(Modification Information) >>
- *
- * 수정일 수정자 수정내용
- * ---------- -------- ---------------------------
- * 2021/09/15 shinmj 최초 생성
- *
- */
-@Slf4j
-@RequiredArgsConstructor
-@Transactional
-@Service
-public class ReserveService extends ReactiveAbstractService {
- private static final String RESERVE_ITEM_CIRCUIT_BREAKER_NAME = "reserve-item";
- private static final String CHECK_RESERVE_MEANS = "realtime";
-
- private final ReserveRepository reserveRepository;
- private final ReserveItemServiceClient reserveItemServiceClient;
- private final CircuitBreakerRegistry circuitBreakerRegistry;
- private final StreamBridge streamBridge;
-
- /**
- * entity -> dto 변환
- *
- * @param reserve
- * @return
- */
- private Mono convertReserveResponseDto(Reserve reserve) {
- return Mono.just(ReserveResponseDto.builder()
- .entity(reserve)
- .build());
- }
-
- /**
- * entity -> 목록 dto 변환
- *
- * @param reserve
- * @return
- */
- private Mono convertReserveListResponseDto(Reserve reserve) {
- return Mono.just(ReserveListResponseDto.builder()
- .entity(reserve)
- .build());
- }
-
- /**
- * 현재 로그인 사용자가 관리자인지 체크
- *
- * @return
- */
- private Mono getIsAdmin() {
- return ReactiveSecurityContextHolder.getContext()
- .map(SecurityContext::getAuthentication)
- .filter(Authentication::isAuthenticated)
- .map(Authentication::getAuthorities)
- .map(grantedAuthorities -> {
- List authorities =
- new ArrayList<>((Collection extends SimpleGrantedAuthority>) grantedAuthorities);
- SimpleGrantedAuthority adminRole = new SimpleGrantedAuthority(Role.ADMIN.getKey());
- return authorities.contains(adminRole);
- });
- }
-
- /**
- * 현재 로그인 사용자 id
- *
- * @return
- */
- private Mono getUserId() {
- return ReactiveSecurityContextHolder.getContext()
- .map(SecurityContext::getAuthentication)
- .filter(Authentication::isAuthenticated)
- .map(Authentication::getPrincipal)
- .map(String.class::cast);
- }
-
- /**
- * 목록 조회
- *
- * @param requestDto
- * @param pageable
- * @return
- */
- @Transactional(readOnly = true)
- public Mono> search(ReserveRequestDto requestDto, Pageable pageable) {
- return reserveRepository.search(requestDto, pageable)
- .switchIfEmpty(Flux.empty())
- .flatMap(this::convertReserveListResponseDto)
- .collectList()
- .zipWith(reserveRepository.searchCount(requestDto, pageable))
- .flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
- }
-
- /**
- * 한건 조회 dto return
- *
- * @param reserveId
- * @return
- */
- @Transactional(readOnly = true)
- public Mono findReserveById(String reserveId) {
- return reserveRepository.findReserveById(reserveId)
- .switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveId))
- .flatMap(this::convertReserveResponseDto);
- }
-
- /**
- * 사용자용 예약 목록 조회 (로그인 사용자의 예약정보만 조회)
- *
- * @param userId
- * @param requestDto
- * @param pageable
- * @return
- */
- @Transactional(readOnly = true)
- public Mono> searchForUser(String userId, ReserveRequestDto requestDto, Pageable pageable) {
- return reserveRepository.searchForUser(requestDto, pageable, userId)
- .switchIfEmpty(Flux.empty())
- .flatMap(this::convertReserveListResponseDto)
- .collectList()
- .zipWith(reserveRepository.searchCountForUser(requestDto, pageable, userId))
- .flatMap(tuple -> Mono.just(new PageImpl<>(tuple.getT1(), pageable, tuple.getT2())));
- }
-
- /**
- * 예약 정보 취소
- *
- * @param reserveId
- * @param cancelRequestDto
- * @return
- */
- public Mono cancel(String reserveId, ReserveCancelRequestDto cancelRequestDto) {
- return getIsAdmin().flatMap(isAdmin -> {
- if (isAdmin) {
- return reserveCancel(reserveId, cancelRequestDto);
- }
- return findById(reserveId)
- .zipWith(getUserId())
- .flatMap(tuple -> {
- if (tuple.getT1().getUserId().equals(tuple.getT2())) {
- return Mono.just(tuple.getT1());
- }
- //해당 예약은 취소할 수 없습니다.
- return Mono.error(new BusinessMessageException(getMessage("valid.cant_cancel")));
- })
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(reserve -> reserveCancel(reserveId, cancelRequestDto));
- });
-
- }
-
- /**
- * 예약 상태 취소로 변경
- *
- * @param reserveId
- * @param cancelRequestDto
- * @return
- */
- private Mono reserveCancel(String reserveId, ReserveCancelRequestDto cancelRequestDto) {
- return findById(reserveId)
- .map(reserve -> {
- if (ReserveStatus.DONE.isEquals(reserve.getReserveStatusId())) {
- //해당 예약은 이미 실행되어 취소할 수 없습니다.
- throw new BusinessMessageException(getMessage("valid.cant_cancel_because_done"));
- }else {
- return reserve.updateStatus(ReserveStatus.CANCEL.getKey())
- .updateReasonCancel(cancelRequestDto.getReasonCancelContent());
- }
- })
- .flatMap(reserve -> Mono.just(reserve.conversionReserveQty()))
- .flatMap(this::updateInventory)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(reserve -> Mono.just(reserve.conversionReserveQty()))
- .flatMap(reserveRepository::save)
- .then();
- }
-
- /**
- * 예약 정보 승인
- *
- * @param reserveId
- * @return
- */
- public Mono approve(String reserveId) {
- return getIsAdmin()
- .flatMap(isAdmin -> {
- if (isAdmin) {
- return Mono.just(reserveId);
- }
- //관리자만 승인할 수 있습니다.
- return Mono.error(new BusinessMessageException(getMessage("valid.manager_approve")));
- })
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(this::checkApprove)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(reserveRepository::save).then();
- }
-
- /**
- * 승인 전 validate check 및 교육인 경우 재고 업데이트
- *
- * @param reserveId
- * @return
- */
- private Mono checkApprove(String reserveId) {
- return findById(reserveId)
- .flatMap(this::checkReserveItems)
- .onErrorResume(throwable -> Mono.error(throwable))
- .map(reserve -> reserve.updateStatus(ReserveStatus.APPROVE.getKey()))
- .flatMap(this::updateInventory);
- }
-
- /**
- * 예약 물품 재고 및 예약 일자 체크
- *
- * @param reserve
- * @return
- */
- private Mono checkReserveItems(Reserve reserve) {
- return reserveItemServiceClient.findById(reserve.getReserveItemId())
- .transform(CircuitBreakerOperator.of(circuitBreakerRegistry.circuitBreaker(RESERVE_ITEM_CIRCUIT_BREAKER_NAME)))
- .onErrorResume(throwable -> Mono.empty())
- .flatMap(reserveItemResponseDto -> {
- // validation check
- if (Category.SPACE.isEquals(reserveItemResponseDto.getCategoryId())) {
- return this.checkSpace(reserveItemResponseDto, reserve);
- }else if (Category.EQUIPMENT.isEquals(reserveItemResponseDto.getCategoryId())) {
- return this.checkEquipment(reserveItemResponseDto, reserve);
- }else if (Category.EDUCATION.isEquals(reserveItemResponseDto.getCategoryId())) {
- return this.checkEducation(reserveItemResponseDto, reserve);
- }
- return Mono.just(reserve);
- });
- }
-
- /**
- * 예약 날짜 validation
- *
- * @param reserveItem
- * @param reserve
- * @return
- */
- private Mono checkReserveDate(ReserveItemResponseDto reserveItem, Reserve reserve) {
- LocalDateTime startDate = reserveItem.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
- reserveItem.getRequestStartDate() : reserveItem.getOperationStartDate();
- LocalDateTime endDate = reserveItem.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
- reserveItem.getRequestEndDate() : reserveItem.getOperationEndDate();
-
- if (reserve.getReserveStartDate().isBefore(startDate)) {
- //{0}이 {1} 보다 빠릅니다. 시작일, 운영/예약 시작일
- return Mono.error(new BusinessMessageException(getMessage("valid.to_be_fast.format", new Object[]{getMessage("common.start_date"),
- getMessage("reserve_item.operation")+getMessage("reserve")+" "+getMessage("common.start_date")})));
- }
-
- if (reserve.getReserveEndDate().isAfter(endDate)) {
- //{0}이 {1} 보다 늦습니다. 종료일, 운영/예약 종료일
- return Mono.error(new BusinessMessageException(getMessage("valid.to_be_slow.format", new Object[]{getMessage("common.end_date"),
- getMessage("reserve_item.operation")+getMessage("reserve")+" "+getMessage("common.end_date")})));
- }
-
- if (reserveItem.getIsPeriod()) {
- long between = ChronoUnit.DAYS.between(reserve.getReserveStartDate(), reserve.getReserveEndDate());
- if (reserveItem.getPeriodMaxCount() < between) {
- //최대 예약 가능 일수보다 예약기간이 깁니다. (최대 예약 가능일 수 : {0})
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_period", new Object[]{reserveItem.getPeriodMaxCount()})));
- }
- }
-
- return Mono.just(reserve);
- }
-
- /**
- * 공간 예약 시 예약 날짜에 다른 예약이 있는지 체크
- *
- * @param reserveItem
- * @param reserve
- * @return
- */
- private Mono checkSpace(ReserveItemResponseDto reserveItem, Reserve reserve) {
- return this.checkReserveDate(reserveItem, reserve)
- .flatMap(isValid -> reserveRepository.findAllByReserveDateWithoutSelfCount(
- reserve.getReserveId(),
- reserveItem.getReserveItemId(),
- reserve.getReserveStartDate(),
- reserve.getReserveEndDate())
- .flatMap(count -> {
- if (count > 0) {
- //"해당 날짜에는 예약할 수 없습니다."
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_date")));
- }
- return Mono.just(reserve);
- })
- );
- }
-
- /**
- * 장비 예약 시 예약 날짜에 예약 가능한 재고 체크
- *
- * @param reserveItem
- * @param reserve
- * @return
- */
- private Mono checkEquipment(ReserveItemResponseDto reserveItem, Reserve reserve) {
- return this.checkReserveDate(reserveItem, reserve)
- .flatMap(entity -> this.getMaxByReserveDateWithoutSelf(
- entity.getReserveId(),
- reserveItem.getReserveItemId(),
- entity.getReserveStartDate(),
- entity.getReserveEndDate())
- .flatMap(max -> {
- if ((reserveItem.getTotalQty() - max) < reserve.getReserveQty()) {
- return Mono.just(false);
- }
- return Mono.just(true);
- })
- .flatMap(isValid -> {
- if (!isValid) {
- //해당 날짜에 예약할 수 있는 재고수량이 없습니다.
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_count")));
- }
- return Mono.just(reserve);
- })
- );
- }
-
- /**
- * 교육 예약 시 재고 체크
- *
- * @param reserveItem
- * @param reserve
- * @return
- */
- private Mono checkEducation(ReserveItemResponseDto reserveItem, Reserve reserve) {
- return Mono.just(reserveItem)
- .flatMap(reserveItemResponseDto -> {
- LocalDateTime now = LocalDateTime.now();
- LocalDateTime startDate = reserveItemResponseDto.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
- reserveItemResponseDto.getRequestStartDate() : reserveItemResponseDto.getOperationStartDate();
- LocalDateTime endDate = reserveItemResponseDto.getReserveMeansId().equals(CHECK_RESERVE_MEANS) ?
- reserveItemResponseDto.getRequestEndDate() : reserveItemResponseDto.getOperationEndDate();
-
- if (!(now.isAfter(startDate) && now.isBefore(endDate))) {
- //해당 날짜에는 예약할 수 없습니다.
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_date")));
- }
-
- if (reserveItemResponseDto.getInventoryQty() <= 0) {
- //"예약이 마감되었습니다."
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_close")));
- }
-
- if (reserveItemResponseDto.getInventoryQty() < reserve.getReserveQty()) {
- //예약가능한 인원이 부족합니다. (남은 인원 : {0})
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_number_of_people", new Object[]{reserveItemResponseDto.getInventoryQty()})));
- }
- return Mono.just(reserve);
- });
- }
-
- /**
- * 예약 정보 수정
- *
- * @param reserveId
- * @return
- */
- public Mono update(String reserveId, ReserveUpdateRequestDto updateRequestDto) {
- return getIsAdmin().flatMap(isAdmin -> {
- if (isAdmin) {
- return updateReserve(reserveId, updateRequestDto);
- }
- return updateReserveForUser(reserveId, updateRequestDto);
- });
- }
-
- /**
- * 사용자 예약 수정
- *
- * @param reserveId
- * @param updateRequestDto
- * @return
- */
- private Mono updateReserveForUser(String reserveId, ReserveUpdateRequestDto updateRequestDto) {
- return findById(reserveId)
- .zipWith(getUserId())
- .map(tuple -> {
- if (!tuple.getT1().getUserId().equals(tuple.getT2())) {
- //"해당 예약은 수정할 수 없습니다."
- throw new BusinessMessageException(getMessage("valid.reserve_not_update"));
- }
-
- if (!ReserveStatus.REQUEST.getKey().equals(tuple.getT1().getReserveStatusId())) {
- //예약 신청 상태인 경우에만 수정 가능합니다.
- throw new BusinessMessageException(getMessage("valid.reserve_not_update_status"));
- }
-
- return tuple.getT1().update(updateRequestDto);
- })
- .flatMap(this::checkReserveItems)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(this::updateInventory)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(reserveRepository::save);
- }
-
- /**
- * 관리자 예약 수정
- *
- * @param reserveId
- * @param updateRequestDto
- * @return
- */
- private Mono updateReserve(String reserveId, ReserveUpdateRequestDto updateRequestDto) {
- return findById(reserveId)
- .map(reserve -> {
- if (!ReserveStatus.REQUEST.getKey().equals(reserve.getReserveStatusId())) {
- //예약 신청 상태인 경우에만 수정 가능합니다.
- throw new BusinessMessageException(getMessage("valid.reserve_not_update_status"));
- }
- return reserve.update(updateRequestDto);
- })
- .flatMap(this::checkReserveItems)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(this::updateInventory)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(reserveRepository::save);
- }
-
- /**
- * 한건 정보 조회 entity return
- *
- * @param reserveId
- * @return
- */
- private Mono findById(String reserveId) {
- return reserveRepository.findById(reserveId)
- .switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveId));
- }
-
- /**
- * 관리자 예약 신청
- * 관리자의 경우 실시간이어도 이벤트 스트림 거치지 않고 바로 예약 처리
- *
- * @param saveRequestDto
- * @return
- */
- public Mono create(ReserveSaveRequestDto saveRequestDto) {
- return Mono.just(saveRequestDto)
- .map(dto -> {
- String uuid = UUID.randomUUID().toString();
- dto.setReserveId(uuid);
- return dto.toEntity();
- })
- .zipWith(getUserId())
- .flatMap(tuple -> Mono.just(tuple.getT1().setCreatedInfo(LocalDateTime.now(), tuple.getT2())))
- .flatMap(this::checkReserveItems)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(this::updateInventory)
- .onErrorResume(throwable -> Mono.error(throwable))
- .flatMap(reserveRepository::insert)
- .flatMap(reserveRepository::loadRelations)
- .doOnNext(reserve -> sendAttachmentEntityInfo(streamBridge,
- AttachmentEntityMessage.builder()
- .attachmentCode(reserve.getAttachmentCode())
- .entityName(reserve.getClass().getName())
- .entityId(reserve.getReserveId())
- .build()))
- .flatMap(this::convertReserveResponseDto);
-
-
- }
-
- /**
- * 예약 정보 저장 시 재고 변경
- *
- * @param reserve
- * @return
- */
- private Mono updateInventory(Reserve reserve) {
- return Mono.just(reserve)
- .flatMap(reserve1 -> {
- if (!Category.EDUCATION.isEquals(reserve1.getCategoryId())) {
- return Mono.just(reserve1);
- }
- return reserveItemServiceClient.updateInventory(reserve.getReserveItemId(), reserve.getReserveQty())
- .transform(CircuitBreakerOperator.of(circuitBreakerRegistry.circuitBreaker(RESERVE_ITEM_CIRCUIT_BREAKER_NAME)))
- .onErrorResume(throwable -> Mono.just(false))
- .flatMap(isSuccess -> {
- if (isSuccess) {
- return Mono.just(reserve);
- }
- //재고 업데이트에 실패했습니다.
- return Mono.error(new BusinessMessageException(getMessage("msg.inventory_failed")));
- });
- });
- }
-
- /**
- * 예약 물품별 기간안에 있는 예약된 수량 max 조회
- *
- * @param reserveItemId
- * @param startDate
- * @param endDate
- * @return
- */
- public Mono countInventory(Long reserveItemId, LocalDateTime startDate, LocalDateTime endDate) {
- return reserveItemServiceClient.findById(reserveItemId)
- .transform(CircuitBreakerOperator.of(circuitBreakerRegistry.circuitBreaker(RESERVE_ITEM_CIRCUIT_BREAKER_NAME)))
- .onErrorResume(throwable -> Mono.empty())
- .zipWith(getMaxByReserveDate(reserveItemId, startDate, endDate))
- .log("countinventory")
- .flatMap(tuple -> Mono.just(tuple.getT1().getTotalQty() - tuple.getT2()));
- }
-
- /**
- * 예약물품에 대해 날짜별 예약된 수량 max 조회
- * 현 예약 건 제외
- *
- * @param reserveItemId
- * @param startDate
- * @param endDate
- * @return
- */
- private Mono getMaxByReserveDateWithoutSelf(String reserveId, Long reserveItemId, LocalDateTime startDate, LocalDateTime endDate) {
- Flux reserveFlux = reserveRepository.findAllByReserveDateWithoutSelf(reserveId, reserveItemId, startDate, endDate)
- .switchIfEmpty(Flux.empty());
- return countMax(reserveFlux, startDate, endDate);
- }
-
- /**
- * 예약물품에 대해 날짜별 예약된 수량 max 조회
- *
- * @param reserveItemId
- * @param startDate
- * @param endDate
- * @return
- */
- private Mono getMaxByReserveDate(Long reserveItemId, LocalDateTime startDate, LocalDateTime endDate) {
- Flux reserveFlux = reserveRepository.findAllByReserveDate(reserveItemId, startDate, endDate)
- .switchIfEmpty(Flux.empty());
- return countMax(reserveFlux, startDate, endDate);
- }
-
- /**
- * get max
- *
- * @param reserveFlux
- * @param startDate
- * @param endDate
- * @return
- */
- private Mono countMax(Flux reserveFlux, LocalDateTime startDate, LocalDateTime endDate) {
- if (reserveFlux.equals(Flux.empty())) {
- return Mono.just(0);
- }
-
- long between = ChronoUnit.DAYS.between(startDate, endDate);
-
- if (between == 0) {
- return reserveFlux.map(reserve -> {
- if (startDate.isAfter(reserve.getReserveStartDate())
- || startDate.isBefore(reserve.getReserveEndDate())
- || startDate.isEqual(reserve.getReserveStartDate()) || startDate.isEqual(reserve.getReserveEndDate())) {
- return reserve.getReserveQty();
- }
- return 0;
- }).reduce(0, (x1, x2) -> x1 + x2);
- }
-
- return Flux.fromStream(IntStream.iterate(0, i -> i + 1)
- .limit(between)
- .mapToObj(i -> startDate.plusDays(i)))
- .flatMap(localDateTime ->
- reserveFlux.map(findReserve -> {
- if (localDateTime.isAfter(findReserve.getReserveStartDate())
- || localDateTime.isBefore(findReserve.getReserveEndDate())
- || localDateTime.isEqual(findReserve.getReserveStartDate()) || localDateTime.isEqual(findReserve.getReserveEndDate())) {
- return findReserve.getReserveQty();
- }
- return 0;
- }).reduce(0, (x1, x2) -> x1 + x2))
- .groupBy(integer -> integer)
- .flatMap(group -> group.reduce((x1,x2) -> x1 > x2?x1:x2))
- .last(0);
- }
-
-}
diff --git a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/validator/ReserveSaveValidator.java b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/validator/ReserveSaveValidator.java
index dd673fa..ca47911 100644
--- a/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/validator/ReserveSaveValidator.java
+++ b/backend/reserve-check-service/src/main/java/org/egovframe/cloud/reservechecksevice/validator/ReserveSaveValidator.java
@@ -2,22 +2,19 @@ package org.egovframe.cloud.reservechecksevice.validator;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
-
import javax.annotation.Resource;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
-
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.util.MessageUtil;
import org.egovframe.cloud.reservechecksevice.validator.annotation.ReserveSaveValid;
import org.springframework.util.StringUtils;
-import lombok.RequiredArgsConstructor;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-
/**
* org.egovframe.cloud.reservechecksevice.validator.ReserveSaveValidator
- *
+ *
* 예약 신청 시 validation check를 하기 위한 custom validator
*
* @author 표준프레임워크센터 shinmj
@@ -42,6 +39,7 @@ public class ReserveSaveValidator implements ConstraintValidator clazz = object.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
@@ -167,10 +182,12 @@ public class ReserveSaveValidator implements ConstraintValidator clazz = object.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
- return field.get(object) == null || !StringUtils.hasLength(String.valueOf(field.get(object)));
+ return field.get(object) == null || !StringUtils
+ .hasLength(String.valueOf(field.get(object)));
}
}
diff --git a/backend/reserve-check-service/src/test/java/org/egovframe/cloud/reservechecksevice/api/ReserveApiControllerTest.java b/backend/reserve-check-service/src/test/java/org/egovframe/cloud/reservechecksevice/api/ReserveApiControllerTest.java
index 2282eb5..6909d24 100644
--- a/backend/reserve-check-service/src/test/java/org/egovframe/cloud/reservechecksevice/api/ReserveApiControllerTest.java
+++ b/backend/reserve-check-service/src/test/java/org/egovframe/cloud/reservechecksevice/api/ReserveApiControllerTest.java
@@ -1,27 +1,26 @@
package org.egovframe.cloud.reservechecksevice.api;
-import static org.assertj.core.api.Assertions.*;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.time.LocalDateTime;
-
import org.egovframe.cloud.common.domain.Role;
import org.egovframe.cloud.common.exception.dto.ErrorCode;
import org.egovframe.cloud.common.exception.dto.ErrorResponse;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveCancelRequestDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveListResponseDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveSaveRequestDto;
-import org.egovframe.cloud.reservechecksevice.api.reserve.dto.ReserveUpdateRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveCancelRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveListResponseDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveSaveRequestDto;
+import org.egovframe.cloud.reservechecksevice.api.dto.ReserveUpdateRequestDto;
import org.egovframe.cloud.reservechecksevice.client.ReserveItemServiceClient;
import org.egovframe.cloud.reservechecksevice.client.UserServiceClient;
import org.egovframe.cloud.reservechecksevice.client.dto.ReserveItemRelationResponseDto;
import org.egovframe.cloud.reservechecksevice.client.dto.ReserveItemResponseDto;
import org.egovframe.cloud.reservechecksevice.client.dto.UserResponseDto;
+import org.egovframe.cloud.reservechecksevice.domain.Reserve;
+import org.egovframe.cloud.reservechecksevice.domain.ReserveItem;
+import org.egovframe.cloud.reservechecksevice.domain.ReserveRepository;
+import org.egovframe.cloud.reservechecksevice.domain.ReserveStatus;
import org.egovframe.cloud.reservechecksevice.domain.location.Location;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.Reserve;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveItem;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveRepository;
-import org.egovframe.cloud.reservechecksevice.domain.reserve.ReserveStatus;
import org.egovframe.cloud.reservechecksevice.util.RestResponsePage;
import org.egovframe.cloud.reservechecksevice.util.WithCustomMockUser;
import org.junit.jupiter.api.AfterEach;
@@ -34,11 +33,9 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.reactive.server.WebTestClient;
-
import reactor.core.publisher.Mono;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@@ -59,8 +56,6 @@ public class ReserveApiControllerTest {
@Autowired
private WebTestClient webTestClient;
- @Autowired
- private R2dbcEntityTemplate entityTemplate;
private static final String API_URL = "/api/v1/reserves";
@@ -118,7 +113,7 @@ public class ReserveApiControllerTest {
}
@Test
- public void 예약신청관리_목록_조회_성공() throws Exception {
+ public void 예약신청관리_목록_조회_성공() {
//given
BDDMockito.when(userServiceClient.findByUserId(ArgumentMatchers.anyString()))
.thenReturn(Mono.just(user));
@@ -146,7 +141,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "admin", role = Role.ADMIN)
- public void 관리자_취소_성공() throws Exception {
+ public void 관리자_취소_성공() {
BDDMockito.when(reserveItemServiceClient.updateInventory(ArgumentMatchers.anyLong(), ArgumentMatchers.anyInt()))
.thenReturn(Mono.just(true));
@@ -189,7 +184,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "test", role = Role.USER)
- public void 다른사용자_예약_취소_실패() throws Exception {
+ public void 다른사용자_예약_취소_실패() {
BDDMockito.when(reserveItemServiceClient.updateInventory(ArgumentMatchers.anyLong(), ArgumentMatchers.anyInt()))
.thenReturn(Mono.just(true));
Reserve saved = reserveRepository.insert(reserve).block();
@@ -209,7 +204,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "user", role = Role.USER)
- public void 예약상태_완료_취소_실패() throws Exception {
+ public void 예약상태_완료_취소_실패() {
Reserve done = reserve.updateStatus(ReserveStatus.DONE.getKey());
Reserve saved = reserveRepository.insert(done).block();
assertNotNull(saved);
@@ -231,7 +226,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "user", role = Role.USER)
- public void 관리자가_아닌_경우_승인_실패() throws Exception {
+ public void 관리자가_아닌_경우_승인_실패() {
Reserve saved = reserveRepository.insert(reserve).block();
assertNotNull(saved);
@@ -252,7 +247,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "admin", role = Role.ADMIN)
- public void 예약승인_성공() throws Exception {
+ public void 예약승인_성공() {
Reserve saved = reserveRepository.insert(reserve).block();
assertNotNull(saved);
@@ -274,7 +269,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "admin", role = Role.ADMIN)
- public void 예약승인_실패_재고부족() throws Exception {
+ public void 예약승인_실패_재고부족() {
ReserveItem failReserveItem = ReserveItem.builder()
.reserveItemId(1L)
.reserveItemName("test")
@@ -313,7 +308,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "admin", role = Role.ADMIN)
- public void 관리자_예약정보_수정_성공() throws Exception {
+ public void 관리자_예약정보_수정_성공() {
Reserve saved = reserveRepository.insert(reserve).block();
assertNotNull(saved);
@@ -351,7 +346,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "test", role = Role.USER)
- public void 다른사용자_예약정보_수정_실패() throws Exception {
+ public void 다른사용자_예약정보_수정_실패() {
Reserve saved = reserveRepository.insert(reserve).block();
assertNotNull(saved);
@@ -387,7 +382,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "user", role = Role.USER)
- public void 사용자_예약정보_수정_성공() throws Exception {
+ public void 사용자_예약정보_수정_성공() {
Reserve saved = reserveRepository.insert(reserve).block();
assertNotNull(saved);
@@ -426,7 +421,7 @@ public class ReserveApiControllerTest {
@Test
@WithCustomMockUser(userId = "user", role = Role.USER)
- public void 사용자_상태승인인예약정보_수정_실패() throws Exception {
+ public void 사용자_상태승인인예약정보_수정_실패() {
Reserve failedReserve = reserve.withReserveStatusId(ReserveStatus.APPROVE.getKey());
Reserve saved = reserveRepository.insert(failedReserve).block();
assertNotNull(saved);
@@ -463,7 +458,7 @@ public class ReserveApiControllerTest {
}
@Test
- public void 관리자_예약_성공() throws Exception {
+ public void 관리자_예약_성공() {
BDDMockito.when(reserveItemServiceClient.findById(ArgumentMatchers.anyLong()))
.thenReturn(Mono.just(ReserveItemResponseDto.builder().reserveItem(reserveItem).build()));
BDDMockito.when(reserveItemServiceClient.updateInventory(ArgumentMatchers.anyLong(), ArgumentMatchers.anyInt()))
@@ -495,7 +490,7 @@ public class ReserveApiControllerTest {
}
@Test
- public void 예약신청_valid_실패() throws Exception {
+ public void 예약신청_valid_실패() {
ReserveItem validReserveItem = ReserveItem.builder()
.reserveItemId(1L)
.reserveItemName("test")
@@ -532,7 +527,7 @@ public class ReserveApiControllerTest {
}
@Test
- public void 물품재고조회_성공() throws Exception {
+ public void 물품재고조회_성공() {
BDDMockito.when(reserveItemServiceClient.findById(ArgumentMatchers.anyLong()))
.thenReturn(Mono.just(ReserveItemResponseDto.builder().reserveItem(reserveItem).build()));
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/ReserveItemServiceApplication.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/ReserveItemServiceApplication.java
index 97fd8c8..40c1512 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/ReserveItemServiceApplication.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/ReserveItemServiceApplication.java
@@ -1,15 +1,11 @@
package org.egovframe.cloud.reserveitemservice;
+import java.security.Security;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
-import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
-
import reactivefeign.spring.config.EnableReactiveFeignClients;
-//import reactor.blockhound.BlockHound;
-
-import java.security.Security;
@ComponentScan({"org.egovframe.cloud.common", "org.egovframe.cloud.reactive", "org.egovframe.cloud.reserveitemservice"}) // org.egovframe.cloud.common package 포함하기 위해
@EnableDiscoveryClient
@@ -25,5 +21,4 @@ public class ReserveItemServiceApplication {
SpringApplication.run(ReserveItemServiceApplication.class, args);
}
-
}
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/LocationApiController.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/LocationApiController.java
index 4a48935..67118b7 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/LocationApiController.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/LocationApiController.java
@@ -1,6 +1,7 @@
package org.egovframe.cloud.reserveitemservice.api.location;
import io.swagger.v3.oas.annotations.Operation;
+import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.dto.RequestDto;
@@ -11,12 +12,18 @@ import org.egovframe.cloud.reserveitemservice.service.location.LocationService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import javax.validation.Valid;
-
/**
* org.egovframe.cloud.reserveitemservice.api.location.LocationApiController
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationResponseDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationResponseDto.java
index bb51565..29da56b 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationResponseDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationResponseDto.java
@@ -1,9 +1,11 @@
package org.egovframe.cloud.reserveitemservice.api.location.dto;
-import lombok.*;
-import org.egovframe.cloud.reserveitemservice.domain.location.Location;
-
import java.time.LocalDateTime;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import org.egovframe.cloud.reserveitemservice.domain.location.Location;
/**
* org.egovframe.cloud.reserveitemservice.api.location.dto.LocationResponseDto
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationSaveRequestDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationSaveRequestDto.java
index 1285d92..03d2194 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationSaveRequestDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationSaveRequestDto.java
@@ -1,13 +1,12 @@
package org.egovframe.cloud.reserveitemservice.api.location.dto;
+import javax.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
-import javax.validation.constraints.NotNull;
-
/**
* org.egovframe.cloud.reserveitemservice.api.location.dto.LocationSaveRequestDto
*
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationUpdateRequestDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationUpdateRequestDto.java
index 8f94449..450ff16 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationUpdateRequestDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/location/dto/LocationUpdateRequestDto.java
@@ -1,12 +1,11 @@
package org.egovframe.cloud.reserveitemservice.api.location.dto;
+import javax.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
-
-import javax.validation.constraints.NotNull;
/**
* org.egovframe.cloud.reserveitemservice.api.location.dto.LocationUpdateRequestDto
*
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/ReserveItemApiController.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/ReserveItemApiController.java
index 997aa23..fb558b5 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/ReserveItemApiController.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/ReserveItemApiController.java
@@ -1,11 +1,10 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
-
import javax.validation.Valid;
-
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemListResponseDto;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemMainResponseDto;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRelationResponseDto;
@@ -26,10 +25,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemListResponseDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemListResponseDto.java
index 59946c8..8a2ff15 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemListResponseDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemListResponseDto.java
@@ -1,14 +1,11 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
+import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
-import org.springframework.util.NumberUtils;
-import org.springframework.util.StringUtils;
-
-import java.time.LocalDateTime;
/**
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemMainResponseDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemMainResponseDto.java
index 57de071..6029d90 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemMainResponseDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemMainResponseDto.java
@@ -1,13 +1,11 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
import java.time.LocalDateTime;
-
-import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
-
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
+import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
@Getter
@NoArgsConstructor
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRelationResponseDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRelationResponseDto.java
index 4e77acc..2292a2a 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRelationResponseDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRelationResponseDto.java
@@ -1,16 +1,14 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
-
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
/**
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRelationResponseDto
*
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRequestDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRequestDto.java
index 00929ac..1324bfe 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRequestDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemRequestDto.java
@@ -1,6 +1,10 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
-import lombok.*;
+import java.util.Objects;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
import org.egovframe.cloud.common.dto.RequestDto;
/**
@@ -28,4 +32,16 @@ public class ReserveItemRequestDto extends RequestDto {
private Long locationId;
private String categoryId;
private Boolean isUse;
+
+ public boolean hasLocationId() {
+ return hasId(locationId);
+ }
+
+ public boolean hasCategoryId() {
+ return hasId(categoryId);
+ }
+
+ private boolean hasId(Object id) {
+ return Objects.nonNull(id) && !Objects.equals("null", id) && !Objects.equals("undefined", id);
+ }
}
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemResponseDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemResponseDto.java
index 5d217b7..7098d14 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemResponseDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemResponseDto.java
@@ -1,12 +1,12 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
-import lombok.*;
-import lombok.experimental.Accessors;
-import org.egovframe.cloud.reserveitemservice.domain.location.Location;
-import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
-
import java.math.BigDecimal;
import java.time.LocalDateTime;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
/**
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemResponseDto
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemSaveRequestDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemSaveRequestDto.java
index 4963ed5..c66da3d 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemSaveRequestDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemSaveRequestDto.java
@@ -1,5 +1,11 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.PositiveOrZero;
+import javax.validation.constraints.Size;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -7,10 +13,6 @@ import lombok.ToString;
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
import org.egovframe.cloud.reserveitemservice.validator.annotation.ReserveItemSaveValid;
-import javax.validation.constraints.*;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
/**
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemSaveRequestDto
*
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemUpdateRequestDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemUpdateRequestDto.java
index 5998df1..664c19a 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemUpdateRequestDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveItemUpdateRequestDto.java
@@ -1,16 +1,17 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.PositiveOrZero;
+import javax.validation.constraints.Size;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
import org.egovframe.cloud.reserveitemservice.validator.annotation.ReserveItemSaveValid;
-import org.hibernate.validator.constraints.Length;
-
-import javax.validation.constraints.*;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
/**
* org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemUpdateRequestDto
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveSaveRequestDto.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveSaveRequestDto.java
index 7514c5e..894c06c 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveSaveRequestDto.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/api/reserveItem/dto/ReserveSaveRequestDto.java
@@ -1,9 +1,12 @@
package org.egovframe.cloud.reserveitemservice.api.reserveItem.dto;
-import lombok.*;
-
-import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
+import javax.validation.constraints.NotNull;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
/**
* org.egovframe.cloud.reserverequestservice.api.dto.ReserveSaveRequestDto
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/ReserveEventConfig.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/ReserveEventConfig.java
index 8cafd6d..3cf1873 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/ReserveEventConfig.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/ReserveEventConfig.java
@@ -1,25 +1,13 @@
package org.egovframe.cloud.reserveitemservice.config;
+import java.util.function.Consumer;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveSaveRequestDto;
import org.egovframe.cloud.reserveitemservice.service.reserveItem.ReserveItemService;
-import org.springframework.amqp.rabbit.connection.ConnectionFactory;
-import org.springframework.amqp.rabbit.core.RabbitTemplate;
-import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
-import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.support.MessageBuilder;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-import reactor.core.scheduler.Scheduler;
-import reactor.core.scheduler.Schedulers;
-
-import java.util.function.Consumer;
-import java.util.function.Function;
/**
* org.egovframe.cloud.reserverequestservice.config.ReserveEventConfig
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/Resilience4JConfig.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/Resilience4JConfig.java
index f92c6c0..04f1975 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/Resilience4JConfig.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/config/Resilience4JConfig.java
@@ -1,12 +1,10 @@
package org.egovframe.cloud.reserveitemservice.config;
-import java.time.Duration;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
+import java.time.Duration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
/**
* org.egovframe.cloud.portalservice.config.Resilience4JConfig
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/location/Location.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/location/Location.java
index 92d1af0..47f1196 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/location/Location.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/location/Location.java
@@ -1,13 +1,15 @@
package org.egovframe.cloud.reserveitemservice.domain.location;
-import lombok.*;
+import javax.validation.constraints.Size;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
import org.egovframe.cloud.reactive.domain.BaseEntity;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
-import javax.validation.constraints.Size;
-
/**
* org.egovframe.cloud.reserveitemservice.domain.location.Location
*
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItem.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItem.java
index 9434957..a3c00bd 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItem.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItem.java
@@ -1,8 +1,14 @@
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
-import lombok.*;
-import lombok.experimental.Accessors;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
import org.egovframe.cloud.reactive.domain.BaseEntity;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemUpdateRequestDto;
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
@@ -11,11 +17,6 @@ import org.springframework.data.annotation.Transient;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
-import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Size;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
/**
* org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem
*
@@ -312,11 +313,11 @@ public class ReserveItem extends BaseEntity {
/**
* 재고 변경
*
- * @param inventoryQty
+ * @param reserveQty
* @return
*/
- public ReserveItem updateInventoryQty(Integer inventoryQty) {
- this.inventoryQty = inventoryQty;
+ public ReserveItem updateInventoryQty(Integer reserveQty) {
+ this.inventoryQty = calcInventoryQty(reserveQty);
return this;
}
@@ -371,6 +372,31 @@ public class ReserveItem extends BaseEntity {
}
}
}
+
+ public String validate(int reserveQty) {
+ if (!Category.EDUCATION.isEquals(categoryId)) {
+ //해당 예약은 수정할 수 없습니다.
+ return "valid.reserve_not_update";
+ }
+
+ LocalDateTime now = LocalDateTime.now();
+ if (!(now.isAfter(requestStartDate) && now.isBefore(requestEndDate))) {
+ //해당 날짜에는 예약할 수 없습니다.
+ return "valid.reserve_date";
+ }
+
+ int qty = calcInventoryQty(reserveQty);
+ if (qty < 0) {
+ //해당 날짜에 예약할 수 있는 재고수량이 없습니다.
+ return "valid.reserve_count";
+ }
+
+ return "valid";
+ }
+
+ private int calcInventoryQty(int reserveQty) {
+ return inventoryQty - reserveQty;
+ }
}
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepository.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepository.java
index 6eb0808..261abb8 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepository.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepository.java
@@ -1,7 +1,6 @@
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
import org.springframework.data.r2dbc.repository.R2dbcRepository;
-import reactor.core.publisher.Flux;
/**
* org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItemRepository
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryCustom.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryCustom.java
index 1f73c57..65389f0 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryCustom.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryCustom.java
@@ -1,12 +1,8 @@
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
-import java.time.LocalDateTime;
-
-import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemMainResponseDto;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto;
import org.egovframe.cloud.reserveitemservice.domain.code.Code;
import org.springframework.data.domain.Pageable;
-
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryImpl.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryImpl.java
index 789b9d7..0198769 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryImpl.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/domain/reserveItem/ReserveItemRepositoryImpl.java
@@ -1,10 +1,11 @@
package org.egovframe.cloud.reserveitemservice.domain.reserveItem;
-import static org.springframework.data.relational.core.query.Criteria.*;
+import static org.springframework.data.relational.core.query.Criteria.where;
import java.util.ArrayList;
import java.util.List;
-
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRequestDto;
import org.egovframe.cloud.reserveitemservice.domain.code.Code;
import org.egovframe.cloud.reserveitemservice.domain.location.Location;
@@ -14,9 +15,6 @@ import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.query.Criteria;
import org.springframework.data.relational.core.query.Query;
import org.springframework.util.StringUtils;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -40,7 +38,7 @@ import reactor.core.publisher.Mono;
@Slf4j
@RequiredArgsConstructor
public class ReserveItemRepositoryImpl implements ReserveItemRepositoryCustom{
-
+ private static final String SORT_COLUMN = "create_date";
private final R2dbcEntityTemplate entityTemplate;
/**
@@ -54,7 +52,7 @@ public class ReserveItemRepositoryImpl implements ReserveItemRepositoryCustom{
public Flux search(ReserveItemRequestDto requestDto, Pageable pageable) {
return entityTemplate.select(ReserveItem.class)
.matching(Query.query(Criteria.from(whereQuery(requestDto)))
- .sort(Sort.by(Sort.Direction.DESC, "create_date"))
+ .sort(Sort.by(Sort.Direction.DESC, SORT_COLUMN))
.with(pageable))
.all()
.flatMap(this::loadRelations)
@@ -72,7 +70,7 @@ public class ReserveItemRepositoryImpl implements ReserveItemRepositoryCustom{
public Mono searchCount(ReserveItemRequestDto requestDto, Pageable pageable) {
return entityTemplate.select(ReserveItem.class)
.matching(Query.query(Criteria.from(whereQuery(requestDto)))
- .sort(Sort.by(Sort.Direction.DESC, "create_date"))
+ .sort(Sort.by(Sort.Direction.DESC, SORT_COLUMN))
.with(pageable))
.count();
}
@@ -101,7 +99,7 @@ public class ReserveItemRepositoryImpl implements ReserveItemRepositoryCustom{
@Override
public Flux findLatestByCategory(Integer count, String categoryId) {
Query query =Query.query(where("category_id").is(categoryId)
- .and("use_at").isTrue()).sort(Sort.by(Sort.Order.desc("create_date")));
+ .and("use_at").isTrue()).sort(Sort.by(Sort.Order.desc(SORT_COLUMN)));
if (count > 0) {
query.limit(count);
@@ -216,17 +214,15 @@ public class ReserveItemRepositoryImpl implements ReserveItemRepositoryCustom{
List whereCriteria = new ArrayList<>();
- if (StringUtils.hasText(keyword)) {
- if ("item".equals(keywordType)) {
- whereCriteria.add(where("reserve_item_name").like(likeText(keyword)));
- }
+ if (StringUtils.hasText(keyword) && "item".equals(keywordType)) {
+ whereCriteria.add(where("reserve_item_name").like(likeText(keyword)));
}
- if (requestDto.getLocationId() != null && !"null".equals(requestDto.getLocationId()) && !"undefined".equals(requestDto.getLocationId())) {
+ if (requestDto.hasLocationId()) {
whereCriteria.add(where("location_id").in(requestDto.getLocationId()));
}
- if (requestDto.getCategoryId() != null && !"null".equals(requestDto.getCategoryId()) && !"undefined".equals(requestDto.getCategoryId())) {
+ if (requestDto.hasCategoryId()) {
whereCriteria.add(where("category_id").in(requestDto.getCategoryId()));
}
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/location/LocationService.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/location/LocationService.java
index 6963e5b..8e2ab88 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/location/LocationService.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/location/LocationService.java
@@ -4,9 +4,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.dto.RequestDto;
import org.egovframe.cloud.common.exception.BusinessMessageException;
-import org.egovframe.cloud.common.exception.EntityNotFoundException;
-import org.egovframe.cloud.common.service.AbstractService;
-import org.egovframe.cloud.common.util.MessageUtil;
import org.egovframe.cloud.reactive.service.ReactiveAbstractService;
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationResponseDto;
import org.egovframe.cloud.reserveitemservice.api.location.dto.LocationSaveRequestDto;
diff --git a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/reserveItem/ReserveItemService.java b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/reserveItem/ReserveItemService.java
index e3ef3d5..7eb2f71 100644
--- a/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/reserveItem/ReserveItemService.java
+++ b/backend/reserve-item-service/src/main/java/org/egovframe/cloud/reserveitemservice/service/reserveItem/ReserveItemService.java
@@ -1,12 +1,10 @@
package org.egovframe.cloud.reserveitemservice.service.reserveItem;
import java.time.Duration;
-import java.time.LocalDateTime;
import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
import java.util.Map;
-
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.egovframe.cloud.common.exception.BusinessMessageException;
import org.egovframe.cloud.reactive.service.ReactiveAbstractService;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemListResponseDto;
@@ -17,7 +15,6 @@ import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemRes
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemSaveRequestDto;
import org.egovframe.cloud.reserveitemservice.api.reserveItem.dto.ReserveItemUpdateRequestDto;
import org.egovframe.cloud.reserveitemservice.config.RequestMessage;
-import org.egovframe.cloud.reserveitemservice.domain.reserveItem.Category;
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItem;
import org.egovframe.cloud.reserveitemservice.domain.reserveItem.ReserveItemRepository;
import org.springframework.cloud.stream.function.StreamBridge;
@@ -27,10 +24,6 @@ import org.springframework.data.domain.Pageable;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
@@ -58,31 +51,14 @@ import reactor.core.scheduler.Schedulers;
public class ReserveItemService extends ReactiveAbstractService {
private static final String RESERVE_CATEGORY_CODE = "reserve-category";
+ private static final String RESERVE_CATEGORY_CODE_ALL = "all";
+ private static final String INVENTORY_UPDATED_BINDING_NAME = "inventoryUpdated-out-0";
+ private static final String EVENT_HEADER_NAME = "reserveUUID";
private final ReserveItemRepository reserveItemRepository;
private final StreamBridge streamBridge;
- /**
- * entity -> dto 변환
- *
- * @param reserveItem
- * @return
- */
- private Mono convertReserveItemResponseDto(ReserveItem reserveItem) {
- return Mono.just(ReserveItemResponseDto.builder().reserveItem(reserveItem).build());
- }
-
- /**
- * entity -> dto 변환
- *
- * @param reserveItem
- * @return
- */
- private Mono convertReserveItemListResponseDto(ReserveItem reserveItem) {
- return Mono.just(ReserveItemListResponseDto.builder().entity(reserveItem).build());
- }
-
/**
* 목록 조회
*
@@ -109,7 +85,7 @@ public class ReserveItemService extends ReactiveAbstractService {
*/
@Transactional(readOnly = true)
public Mono> searchForUser(String categoryId, ReserveItemRequestDto requestDto, Pageable pageable) {
- if (!"all".equals(categoryId)) {
+ if (!RESERVE_CATEGORY_CODE_ALL.equals(categoryId)) {
requestDto.setCategoryId(categoryId);
}
return reserveItemRepository.search(requestDto, pageable)
@@ -203,24 +179,11 @@ public class ReserveItemService extends ReactiveAbstractService {
return reserveItemRepository.findById(reserveItemId)
.switchIfEmpty(monoResponseStatusEntityNotFoundException(reserveItemId))
.flatMap(reserveItem -> {
- if (!Category.EDUCATION.isEquals(reserveItem.getCategoryId())) {
- //해당 예약은 수정할 수 없습니다.
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_not_update")));
+ String validate = reserveItem.validate(reserveQty);
+ if (!"valid".equals(validate)) {
+ return Mono.error(new BusinessMessageException(getMessage(validate)));
}
-
- LocalDateTime now = LocalDateTime.now();
- if (!(now.isAfter(reserveItem.getRequestStartDate()) && now.isBefore(reserveItem.getRequestEndDate()))) {
- //해당 날짜에는 예약할 수 없습니다.
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_date")));
- }
-
- int qty = reserveItem.getInventoryQty() - reserveQty;
- if (qty < 0) {
- //해당 날짜에 예약할 수 있는 재고수량이 없습니다.
- return Mono.error(new BusinessMessageException(getMessage("valid.reserve_count")));
- }
-
- return Mono.just(reserveItem.updateInventoryQty(qty));
+ return Mono.just(reserveItem.updateInventoryQty(reserveQty));
})
.flatMap(reserveItemRepository::save)
.delayElement(Duration.ofSeconds(5))
@@ -236,23 +199,6 @@ public class ReserveItemService extends ReactiveAbstractService {
}
-
- /**
- * 재고 변경 성공 여부 이벤트 발생
- *
- * @param reserveId
- * @param isItemUpdated
- */
- private void sendMessage(String reserveId, Boolean isItemUpdated) {
- streamBridge.send("inventoryUpdated-out-0",
- MessageBuilder.withPayload(
- RequestMessage.builder()
- .reserveId(reserveId)
- .isItemUpdated(isItemUpdated)
- .build())
- .setHeader("reserveUUID", reserveId).build());
- }
-
/**
* 한건 조회 - 연관된 데이터도 같이 조회 (e.g. codename, location)
*
@@ -274,13 +220,48 @@ public class ReserveItemService extends ReactiveAbstractService {
* @return
*/
public Mono