Skip to content

Commit

Permalink
Merge branch 'feature/item' of https://github.com/Orange-Co/DDANZI_Se…
Browse files Browse the repository at this point in the history
…rver into develop
  • Loading branch information
Kang1221 committed Nov 5, 2024
2 parents 07809c7 + d4963d6 commit ec4ef35
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 25 deletions.
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
implementation 'com.nimbusds:nimbus-jose-jwt:3.1'
//jackson
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.0'
// GCP
implementation group: 'com.google.cloud', name: 'google-cloud-storage', version: '2.40.1'
// Google Firebase Admin
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package co.orange.ddanzi.dto.payment;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class PortOneTokenRequestDto {
@JsonProperty("imp_key")
private String imp_key;
@JsonProperty("imp_secret")
private String imp_secret;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
package co.orange.ddanzi.global.restTemplete;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

@Configuration
public class RestTempleteConfig {

Expand All @@ -21,4 +30,35 @@ public RestTemplate restTemplate(RestTemplateBuilder builder) {
.rootUri(hostUrl+":"+port)
.build();
}

public class LoggingInterceptor implements ClientHttpRequestInterceptor {
private static final Logger log = LoggerFactory.getLogger(LoggingInterceptor.class);

@Override
public ClientHttpResponse intercept(
org.springframework.http.HttpRequest request,
byte[] body,
org.springframework.http.client.ClientHttpRequestExecution execution) throws IOException {

log.info("Request URI: {}", request.getURI());
log.info("Request Method: {}", request.getMethod());
log.info("Request Headers: {}", request.getHeaders());
log.info("Request Body: {}", new String(body, StandardCharsets.UTF_8));

ClientHttpResponse response = execution.execute(request, body);

BufferedReader reader = new BufferedReader(new InputStreamReader(response.getBody(), StandardCharsets.UTF_8));
StringBuilder responseBody = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
responseBody.append(line);
}

log.info("Response Status Code: {}", response.getStatusCode());
log.info("Response Headers: {}", response.getHeaders());
log.info("Response Body: {}", responseBody.toString());

return response;
}
}
}
16 changes: 14 additions & 2 deletions src/main/java/co/orange/ddanzi/service/ItemService.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;


@Slf4j
Expand All @@ -54,6 +56,7 @@ public class ItemService {
private final GcsService gcsService;
private final TermService termService;
private final AddressService addressService;
private final ProductService productService;
private final PaymentService paymentService;
private final PaymentRepository paymentRepository;
private final HistoryService historyService;
Expand Down Expand Up @@ -87,8 +90,12 @@ public ApiResponse<?> saveItem(SaveItemRequestDto requestDto){

product.updateStock(product.getStock() + 1);
log.info("상품의 재고 수량 업데이트 -> {}개", product.getStock());
if(product.getClosestDueDate()==null || dueDate.isBefore(product.getClosestDueDate()))

if(product.getClosestDueDate()==null || dueDate.isBefore(product.getClosestDueDate())) {
product.updateClosestDueDate(dueDate);
log.info("가장 가까운 마감일을 수정 -> {}", dueDate);

}

SaveItemResponseDto responseDto = SaveItemResponseDto.builder()
.itemId(newItem.getId())
Expand Down Expand Up @@ -167,9 +174,14 @@ public ApiResponse<?> deleteItem(String itemId){
}
log.info("제품을 삭제합니다.");
item.updateStatus(ItemStatus.DELETED);
log.info("재고를 감소시킵니다.");

Product product = item.getProduct();
product.updateStock(product.getStock() - 1);
log.info("재고를 감소시킴 -> {}개", product.getClosestDueDate());

productService.updateClosestDueDate(product);

log.info("가장 가까운 마감일을 수정합 -> {}", product.getClosestDueDate());

return ApiResponse.onSuccess(Success.DELETE_ITEM_SUCCESS, true);
}
Expand Down
21 changes: 13 additions & 8 deletions src/main/java/co/orange/ddanzi/service/OrderService.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,25 @@ public Order getOrderRecord(String orderId){
@Transactional
public void checkOrderPlacedOrder(){
//입금 후 1일(24시간)이 지났는데, 판매확정이 되지 않았을 시 - 거래 취소
LocalDateTime oneDayLimit = LocalDateTime.now().minusMinutes(1);
LocalDateTime oneDayLimit = LocalDateTime.now().minusDays(1);
List<Order> orderPlaceOrders = orderRepository.findOverLimitTimeOrders(OrderStatus.ORDER_PLACE, oneDayLimit);
for(Order order : orderPlaceOrders){
paymentService.refundPayment(order.getBuyer(), order, "고객이 판매확정을 하지 않아 거래가 취소되어 결제 금액을 환불합니다.");
order.updateStatus(OrderStatus.CANCELLED);
fcmService.sendMessageToUser(order.getItem().getSeller(), FcmCase.A2, order);
fcmService.sendMessageToUser(order.getBuyer(), FcmCase.B1, order);
if(paymentService.refundPayment(order.getBuyer(), order, "고객이 판매확정을 하지 않아 거래가 취소되어 결제 금액을 환불합니다.")){
fcmService.sendMessageToAdmins("⚠️ 관리자 알림: 환불 성공", "거래 취소로 인해 환불되었습니다. orderId:" + order.getId());
order.updateStatus(OrderStatus.CANCELLED);
fcmService.sendMessageToUser(order.getItem().getSeller(), FcmCase.A2, order);
fcmService.sendMessageToUser(order.getBuyer(), FcmCase.B1, order);
}
else{
fcmService.sendMessageToAdmins("‼️관리자 알림: 환불 실패", "거래가 취소로 인한 환불에 실패하였습니다. orderId:" + order.getId());
}
}
}

@Transactional
public void checkShippingOrder(){
//판매확정 후 3일 (72시간)이 지났는데, 구매확정이 되지 않았을 시
LocalDateTime threeDayLimit = LocalDateTime.now().minusMinutes(3);
LocalDateTime threeDayLimit = LocalDateTime.now().minusDays(3);
List<Order> shippingOrders = orderRepository.findOverLimitTimeOrders(OrderStatus.SHIPPING, threeDayLimit);
for(Order order : shippingOrders){
fcmService.sendMessageToUser(order.getBuyer(), FcmCase.B3, order);
Expand All @@ -197,7 +202,7 @@ public void checkShippingOrder(){
@Transactional
public void checkDelayedShippingOrder(){
//판매확정 후 6일 (144시간)이 지났는데, 구매확정이 되지 않았고, 신고도 하지 않았을 시
LocalDateTime sixDayLimit = LocalDateTime.now().minusMinutes(3);
LocalDateTime sixDayLimit = LocalDateTime.now().minusDays(3);
List<Order> delayedShippingOrders = orderRepository.findOverLimitTimeOrders(OrderStatus.DELAYED_SHIPPING, sixDayLimit);
for(Order order : delayedShippingOrders){
fcmService.sendMessageToUser(order.getBuyer(), FcmCase.B4, order);
Expand All @@ -208,7 +213,7 @@ public void checkDelayedShippingOrder(){
@Transactional
public void checkWarningOrder(){
//판매확정 후 7일 (168시간)이 지났는데, 구매확정이 되지 않았고, 신고도 하지 않았을 시
LocalDateTime sevenDayLimit = LocalDateTime.now().minusMinutes(1);
LocalDateTime sevenDayLimit = LocalDateTime.now().minusDays(1);
List<Order> delayedShippingOrders = orderRepository.findOverLimitTimeOrders(OrderStatus.WARNING, sevenDayLimit);
for(Order order : delayedShippingOrders){
fcmService.sendMessageToUser(order.getItem().getSeller(), FcmCase.A3, order);
Expand Down
43 changes: 30 additions & 13 deletions src/main/java/co/orange/ddanzi/service/PaymentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@
import co.orange.ddanzi.repository.*;
import co.orange.ddanzi.service.common.FcmService;
import co.orange.ddanzi.service.common.HistoryService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;


import java.util.HashMap;
import java.util.Map;

@Slf4j
Expand All @@ -45,6 +50,8 @@ public class PaymentService {
private final OrderService orderService;
private final HistoryService historyService;
private final FcmService fcmService;
private final ProductService productService;
private final ItemService itemService;

@Value("${ddanzi.portone.access-key}")
private String accessKey;
Expand Down Expand Up @@ -90,12 +97,14 @@ public ApiResponse<?> endPayment(UpdatePaymentRequestDto requestDto){
Item newItem = itemRepository.findNearestExpiryItem(product).orElse(null);
if(newItem == null){
log.info("환불을 진행합니다.");
try {
refundPayment(buyer, order, "현재 남은 재고가 없어 고객에게 결제 금액 환불합니다.");
if(refundPayment(buyer, order, "현재 남은 재고가 없어 고객에게 결제 금액 환불합니다.")){
fcmService.sendMessageToAdmins("⚠️관리자 알림: 환불 성공", "중복 결제로 인해 환불되었습니다. orderId:" + order.getId());
payment.updatePaymentStatusAndEndedAt(PayStatus.CANCELLED);
historyService.createPaymentHistoryWithError(buyer, payment, "재고 없음- 환불 처리 성공");
return ApiResponse.onFailure(Error.NO_ITEM_ON_SALE, Map.of("orderId", order.getId()));
}catch (Exception e){
}
else{
fcmService.sendMessageToAdmins("‼️관리자 알림: 환불 실패", "중복 결제로 인한 환불에 실패하였습니다. orderId:" + order.getId());
historyService.createPaymentHistoryWithError(buyer, payment, "재고 없음 - 환불 처리 실패");
return ApiResponse.onFailure(Error.REFUND_FAILED, Map.of("orderId", order.getId()));
}
Expand Down Expand Up @@ -125,6 +134,8 @@ else if(payment.getPayStatus().equals(PayStatus.PAID)){
log.info("Payment is paid!!");
item.updateStatus(ItemStatus.CLOSED);
product.updateStock(product.getStock() - 1);
productService.updateClosestDueDate(product);
log.info("가장 가까운 마감일을 수정합 -> {}", product.getClosestDueDate());
fcmService.sendMessageToAdmins("⚠️관리자 알림: 구매실행", "결제가 실행되었습니다. orderId:" + order.getId());
}

Expand Down Expand Up @@ -166,23 +177,29 @@ public String getPortOneAccessToken(){
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");

PortOneTokenRequestDto requestBody = PortOneTokenRequestDto.builder()
PortOneTokenRequestDto requestDto = PortOneTokenRequestDto.builder()
.imp_key(accessKey)
.imp_secret(accessSecret)
.build();

HttpEntity<PortOneTokenRequestDto> entity = new HttpEntity<>(requestBody, headers);

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<PortOneTokenResponseDto> response = restTemplate.exchange(url, HttpMethod.POST, entity, PortOneTokenResponseDto.class);
log.info("포트원 Access key Get 성공");
return response.getBody().getResponse().getAccess_token();
try {
ResponseEntity<PortOneTokenResponseDto> response = restTemplate.postForEntity(url, new HttpEntity<>(requestDto, headers), PortOneTokenResponseDto.class);
log.info("포트원 Access key Get 성공");
return response.getBody().getResponse().getAccess_token();
} catch (HttpClientErrorException e) {
log.error("HTTP 오류 발생: 상태 코드 {}, 응답 본문 {}", e.getStatusCode(), e.getResponseBodyAsString());
} catch (RestClientException e) {
log.error("REST 클라이언트 오류 발생: {}", e.getMessage());
} catch (Exception e) {
log.error("기타 오류 발생: {}", e.getMessage());
}
return null;
}

public void refundPayment(User user, Order order, String reason){
public boolean refundPayment(User user, Order order, String reason){
if(!user.equals(order.getBuyer()))
throw new RuntimeException("결제자와 요청자가 다르므로 환불이 어렵습니다.");

try{
String baseUrl = "https://api.iamport.kr/payments/cancel";
String url = UriComponentsBuilder.fromUriString(baseUrl)
Expand All @@ -205,10 +222,10 @@ public void refundPayment(User user, Order order, String reason){
RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(url, entity, String.class);
log.info("결제 취소 api 호출");
fcmService.sendMessageToAdmins("⚠️관리자 알림: 환불실행", "중복 결제로 인해 환불되었습니다. orderId:" + order.getId());
return true;
}catch (Exception e){
log.info("환불 실패");
fcmService.sendMessageToAdmins("⚠️관리자 알림: 환불 실패", "환불에 실패했습니다. orderId:" + order.getId());
return false;
}

}
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/co/orange/ddanzi/service/ProductService.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package co.orange.ddanzi.service;

import co.orange.ddanzi.common.error.Error;
import co.orange.ddanzi.common.exception.DiscountNotFoundException;
import co.orange.ddanzi.common.exception.ProductNotFoundException;
import co.orange.ddanzi.domain.product.Discount;
import co.orange.ddanzi.domain.product.Item;
import co.orange.ddanzi.domain.product.Product;
import co.orange.ddanzi.domain.user.Account;
import co.orange.ddanzi.domain.user.Address;
import co.orange.ddanzi.domain.user.User;
import co.orange.ddanzi.common.response.ApiResponse;
import co.orange.ddanzi.common.response.Success;
Expand All @@ -25,6 +24,7 @@
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Optional;


@Slf4j
Expand All @@ -33,6 +33,7 @@
public class ProductService {
private final AuthUtils authUtils;
private final ProductRepository productRepository;
private final ItemRepository itemRepository;
private final DiscountRepository discountRepository;
private final AccountRepository accountRepository;

Expand Down Expand Up @@ -90,6 +91,13 @@ public String getMostSimilarProductId(ProductRequestDto requestDto){
}
}

public void updateClosestDueDate(Product product){
Optional<Item> item = itemRepository.findNearestExpiryItem(product);
if(item.isPresent())
product.updateClosestDueDate(item.get().getDueDate());
else
product.updateClosestDueDate(null);
}

/*
@Transactional
Expand Down

0 comments on commit ec4ef35

Please sign in to comment.