From 16c719648db21e08597c0bfe0e2aab627d8e5719 Mon Sep 17 00:00:00 2001 From: WestSilver99 Date: Wed, 24 Jan 2024 16:43:54 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat=20:=20=EB=93=B1=EB=A1=9D=EB=90=9C=20?= =?UTF-8?q?=EA=B3=84=EC=A2=8C=20=EC=97=86=EC=9C=BC=EB=A9=B4=20=EC=96=91?= =?UTF-8?q?=EB=8F=84=20=EB=AA=BB=ED=95=98=EA=B2=8C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../goldenticket/domain/nego/service/NegoServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/site/goldenticket/domain/nego/service/NegoServiceImpl.java b/src/main/java/site/goldenticket/domain/nego/service/NegoServiceImpl.java index 4e67b517..2cd7113f 100644 --- a/src/main/java/site/goldenticket/domain/nego/service/NegoServiceImpl.java +++ b/src/main/java/site/goldenticket/domain/nego/service/NegoServiceImpl.java @@ -241,7 +241,7 @@ public HandoverResponse handOverProduct(Long productId, PrincipalDetails princip if (transferPendingNego.isEmpty()) { Order order = orderRepository.findByProductId(productId); - //checkAccountAndThrowException(user); + checkAccountAndThrowException(user); product.setProductStatus(ProductStatus.SOLD_OUT); productService.updateProductForNego(product); handleNegos(allNegosForProduct); @@ -249,7 +249,7 @@ public HandoverResponse handOverProduct(Long productId, PrincipalDetails princip } if (transferPendingNego.isPresent()) { - //checkAccountAndThrowException(user); + checkAccountAndThrowException(user); Nego nego = transferPendingNego.get(); completeTransfer(product, nego); handleNegos(allNegosForProduct); From 3e017e6c997af0933dbb2f1eb8c4827054fcf61e Mon Sep 17 00:00:00 2001 From: WestSilver99 Date: Wed, 24 Jan 2024 17:20:04 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat=20:=20=EB=84=A4=EA=B3=A0=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=EC=9D=B4=20=EC=95=84=EB=8B=8C=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=20=EC=83=81=ED=83=9C=EC=97=90=EC=84=9C=20=EC=B0=BE?= =?UTF-8?q?=EB=8A=94=EA=B1=B0=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nego/service/NegoSchedulerService.java | 92 +++++++++++-------- .../domain/payment/model/Order.java | 4 + .../payment/repository/OrderRepository.java | 2 + 3 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java b/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java index dd687c48..2722aded 100644 --- a/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java +++ b/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java @@ -1,13 +1,5 @@ package site.goldenticket.domain.nego.service; -import static site.goldenticket.common.response.ErrorCode.USER_NOT_FOUND; -import static site.goldenticket.domain.nego.status.NegotiationStatus.NEGOTIATION_COMPLETED; -import static site.goldenticket.domain.nego.status.NegotiationStatus.NEGOTIATION_TIMEOUT; -import static site.goldenticket.domain.nego.status.NegotiationStatus.PAYMENT_PENDING; -import static site.goldenticket.domain.nego.status.NegotiationStatus.TRANSFER_PENDING; - -import java.time.LocalDateTime; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -15,12 +7,22 @@ import site.goldenticket.domain.alert.service.AlertService; import site.goldenticket.domain.nego.entity.Nego; import site.goldenticket.domain.nego.repository.NegoRepository; +import site.goldenticket.domain.payment.model.Order; +import site.goldenticket.domain.payment.repository.OrderRepository; import site.goldenticket.domain.product.constants.ProductStatus; import site.goldenticket.domain.product.model.Product; import site.goldenticket.domain.product.service.ProductService; import site.goldenticket.domain.user.entity.User; import site.goldenticket.domain.user.repository.UserRepository; +import java.time.LocalDateTime; +import java.util.List; + +import static site.goldenticket.common.constants.OrderStatus.COMPLETED_TRANSFER; +import static site.goldenticket.common.constants.OrderStatus.WAITING_TRANSFER; +import static site.goldenticket.common.response.ErrorCode.USER_NOT_FOUND; +import static site.goldenticket.domain.nego.status.NegotiationStatus.*; + @Service @RequiredArgsConstructor public class NegoSchedulerService { @@ -29,12 +31,13 @@ public class NegoSchedulerService { private final ProductService productService; private final AlertService alertService; private final UserRepository userRepository; + private final OrderRepository orderRepository; @Scheduled(fixedDelay = 60000) public void changeStatus() { LocalDateTime currentTime = LocalDateTime.now(); List pendingNegos = negoRepository.findByStatus(PAYMENT_PENDING); - List transferNegos = negoRepository.findByStatus(TRANSFER_PENDING); + List transferOrders = orderRepository.findByStatus(WAITING_TRANSFER); for (Nego nego : pendingNegos) { Product product = productService.getProduct(nego.getProductId()); @@ -47,45 +50,56 @@ public void changeStatus() { //판매자에게 타임오버 알림 전송 alertService.createAlert(product.getUserId(), - "구매자가 20분 이내에 결제를 완료하지 않아 거래가 이루어지지 않았습니다."); + "구매자가 20분 이내에 결제를 완료하지 않아 거래가 이루어지지 않았습니다."); //구매자에게 타임오버 알림 전송 alertService.createAlert(nego.getUser().getId(), - "20분이 초과되었습니다. 아직 구매를 원하신다면, 재결제 버튼을 눌러 결제해주세요."); + "20분이 초과되었습니다. 아직 구매를 원하신다면, 재결제 버튼을 눌러 결제해주세요."); + negoRepository.save(nego); } } //상품 상태 판매중 - for (Nego transferNego : transferNegos) { - Product product = productService.getProduct(transferNego.getProductId()); - LocalDateTime updatedAt = transferNego.getUpdatedAt(); + for (Order transferOrder : transferOrders) { + Product product = productService.getProduct(transferOrder.getProductId()); + List transferNegos = negoRepository.findAllByProduct(product); + LocalDateTime updatedAt = transferOrder.getUpdatedAt(); + if (updatedAt != null && currentTime.isAfter(updatedAt.plusMinutes(20))) { - transferNego.setStatus(NEGOTIATION_COMPLETED); - transferNego.setUpdatedAt(currentTime); - product.setProductStatus(ProductStatus.SOLD_OUT); - productService.updateProductForNego(product); + for (Nego transferNego : transferNegos) { + // 각 네고의 현재 상태를 확인하고 처리 + if (transferNego.getStatus() == NEGOTIATION_COMPLETED) { + continue; + } + transferOrder.setStatus(COMPLETED_TRANSFER); + transferNego.setStatus(NEGOTIATION_COMPLETED); + transferNego.setUpdatedAt(currentTime); - //구매자에게 양도 완료 알림 전송 - alertService.createAlert(transferNego.getUser().getId(), - "'" + product.getAccommodationName() + "(" + product.getRoomName() - + ")'상품 양도가 완료되었습니다. " - + "양도 완료에 따른 체크인 정보는 '마이페이지 > 구매내역 > 구매 완료'에서 확인하실 수 있습니다."); - //판매자에게 정산 요청 알림 전송 - alertService.createAlert(product.getUserId(), - "'" + product.getAccommodationName() + "(" + product.getRoomName() - + ")'상품 양도가 완료되었습니다. 영업일 1일 이내 등록한 계좌 정보로 정산 금액이 입금됩니다." - + "원활한 정산 진행을 위해 '마이페이지 - 나의 계좌'정보를 다시 한번 확인해주세요."); - //판매자에게 계좌 등록 알림 전송 - User user = userRepository.findById(product.getUserId()) - .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); - if (user!=null && user.getAccountNumber() == null) { + // 상품의 상태를 변경하고 업데이트 + product.setProductStatus(ProductStatus.SOLD_OUT); + productService.updateProductForNego(product); + + // 구매자에게 양도 완료 알림 전송 + alertService.createAlert(transferNego.getUser().getId(), + "'" + product.getAccommodationName() + "(" + product.getRoomName() + + ")'상품 양도가 완료되었습니다. " + + "양도 완료에 따른 체크인 정보는 '마이페이지 > 구매내역 > 구매 완료'에서 확인하실 수 있습니다."); + + // 판매자에게 정산 요청 알림 전송 alertService.createAlert(product.getUserId(), - "'" + product.getAccommodationName() + "(" + product.getRoomName() - + ")'상품에 대한 원활한 정산을 위해 '마이페이지 > 내 계좌'에서 입금받으실 계좌를 등록해주세요."); + "'" + product.getAccommodationName() + "(" + product.getRoomName() + + ")'상품 양도가 완료되었습니다. 영업일 1일 이내 등록한 계좌 정보로 정산 금액이 입금됩니다." + + "원활한 정산 진행을 위해 '마이페이지 - 나의 계좌'정보를 다시 한번 확인해주세요."); + + // 판매자에게 계좌 등록 알림 전송 + User user = userRepository.findById(product.getUserId()) + .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); + if (user != null && user.getAccountNumber() == null) { + alertService.createAlert(product.getUserId(), + "'" + product.getAccommodationName() + "(" + product.getRoomName() + + ")'상품에 대한 원활한 정산을 위해 '마이페이지 > 내 계좌'에서 입금받으실 계좌를 등록해주세요."); + } } + negoRepository.saveAll(transferNegos); } - } // 20분 뒤 자동양도 - - negoRepository.saveAll(transferNegos); - negoRepository.saveAll(pendingNegos); + } // 20분 뒤 자동양도 } - } diff --git a/src/main/java/site/goldenticket/domain/payment/model/Order.java b/src/main/java/site/goldenticket/domain/payment/model/Order.java index cf46548d..7651e192 100644 --- a/src/main/java/site/goldenticket/domain/payment/model/Order.java +++ b/src/main/java/site/goldenticket/domain/payment/model/Order.java @@ -58,4 +58,8 @@ public void paymentFailed() { public void changeViewCheck() { customerViewCheck = true; } + + public void setStatus(OrderStatus status) { + this.status = status; + } } diff --git a/src/main/java/site/goldenticket/domain/payment/repository/OrderRepository.java b/src/main/java/site/goldenticket/domain/payment/repository/OrderRepository.java index 8fb250aa..1dc3a296 100644 --- a/src/main/java/site/goldenticket/domain/payment/repository/OrderRepository.java +++ b/src/main/java/site/goldenticket/domain/payment/repository/OrderRepository.java @@ -16,4 +16,6 @@ public interface OrderRepository extends JpaRepository { Order findByProductId(Long productId); List findByUserIdAndStatus(Long userId, OrderStatus status); + + List findByStatus(OrderStatus orderStatus); } From 1d9534408ff9a57cc98d3970a18ef32fe07e3346 Mon Sep 17 00:00:00 2001 From: WestSilver99 Date: Wed, 24 Jan 2024 17:24:47 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat=20:=20=EC=9E=90=EB=8F=99=EC=96=91?= =?UTF-8?q?=EB=8F=84=EC=97=90=EB=8F=84=20=EA=B3=84=EC=A2=8C=EC=97=86?= =?UTF-8?q?=EC=9D=84=EC=8B=9C=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/nego/service/NegoSchedulerService.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java b/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java index 2722aded..73ddec19 100644 --- a/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java +++ b/src/main/java/site/goldenticket/domain/nego/service/NegoSchedulerService.java @@ -4,6 +4,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import site.goldenticket.common.exception.CustomException; +import site.goldenticket.common.response.ErrorCode; import site.goldenticket.domain.alert.service.AlertService; import site.goldenticket.domain.nego.entity.Nego; import site.goldenticket.domain.nego.repository.NegoRepository; @@ -63,6 +64,11 @@ public void changeStatus() { List transferNegos = negoRepository.findAllByProduct(product); LocalDateTime updatedAt = transferOrder.getUpdatedAt(); + User user = userRepository.findById(product.getUserId()) + .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); + + checkAccountAndThrowException(user); + if (updatedAt != null && currentTime.isAfter(updatedAt.plusMinutes(20))) { for (Nego transferNego : transferNegos) { // 각 네고의 현재 상태를 확인하고 처리 @@ -90,8 +96,7 @@ public void changeStatus() { + "원활한 정산 진행을 위해 '마이페이지 - 나의 계좌'정보를 다시 한번 확인해주세요."); // 판매자에게 계좌 등록 알림 전송 - User user = userRepository.findById(product.getUserId()) - .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); + if (user != null && user.getAccountNumber() == null) { alertService.createAlert(product.getUserId(), "'" + product.getAccommodationName() + "(" + product.getRoomName() @@ -102,4 +107,9 @@ public void changeStatus() { } } // 20분 뒤 자동양도 } + private void checkAccountAndThrowException(User user) { + if (user.getAccountNumber() == null) { + throw new CustomException("등록된 계좌가 없습니다.", ErrorCode.NO_REGISTERED_ACCOUNT); + } + } }