diff --git a/src/main/java/org/swmaestro/repl/gifthub/giftcard/repository/GiftcardRepository.java b/src/main/java/org/swmaestro/repl/gifthub/giftcard/repository/GiftcardRepository.java index 694290e7..51cde233 100644 --- a/src/main/java/org/swmaestro/repl/gifthub/giftcard/repository/GiftcardRepository.java +++ b/src/main/java/org/swmaestro/repl/gifthub/giftcard/repository/GiftcardRepository.java @@ -1,8 +1,12 @@ package org.swmaestro.repl.gifthub.giftcard.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.swmaestro.repl.gifthub.giftcard.entity.Giftcard; public interface GiftcardRepository extends JpaRepository { - public boolean existsByVoucherId(Long id); + boolean existsByVoucherId(Long id); + + Optional findAllByVoucherId(Long id); } diff --git a/src/main/java/org/swmaestro/repl/gifthub/giftcard/service/GiftcardService.java b/src/main/java/org/swmaestro/repl/gifthub/giftcard/service/GiftcardService.java index b9d644d2..8f8e7d78 100644 --- a/src/main/java/org/swmaestro/repl/gifthub/giftcard/service/GiftcardService.java +++ b/src/main/java/org/swmaestro/repl/gifthub/giftcard/service/GiftcardService.java @@ -70,6 +70,12 @@ public Giftcard read(String id) { return giftCardRepository.findById(id).get(); } + public Giftcard read(Long voucherId) { + return giftCardRepository.findAllByVoucherId(voucherId) + .filter(giftcard -> giftcard.getExpiresAt().isAfter(LocalDateTime.now())) + .orElseThrow(() -> new BusinessException("존재하지 않는 기프트 카드입니다.", StatusEnum.NOT_FOUND)); + } + /** * 기프트 카드를 조회합니다. * @param id: 조회할 기프트 카드의 id @@ -184,4 +190,11 @@ private String encryptPassword(String password) { byte[] encrypt = aesBytesEncryptor.encrypt(bytes); return ByteArrayUtils.byteArrayToString(encrypt); } + + public Giftcard delete(String id) { + Giftcard giftcard = giftCardRepository.findById(id).orElseThrow(() -> new BusinessException("존재하지 않는 기프트 카드입니다.", StatusEnum.NOT_FOUND)); + giftcard.expire(); + save(giftcard); + return giftcard; + } } diff --git a/src/main/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherController.java b/src/main/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherController.java index 1c60eeef..77c01963 100644 --- a/src/main/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherController.java +++ b/src/main/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherController.java @@ -206,4 +206,20 @@ public ResponseEntity shareVoucher(HttpServletRequest request, @PathVar .data(voucherShareResponseDto) .build()); } + + @DeleteMapping("/{voucherId}/share") + @PreAuthorize("hasRole('ROLE_USER')") + @Operation(summary = "Voucher 공유 취소 메서드", description = "클라이언트에서 요청한 기프티콘을 공유를 취소하기 위한 메서드입니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "기프트 카드 삭제 성공"), + @ApiResponse(responseCode = "404", description = "존재하지 않는 기프트 카드 삭제 시도"), + }) + public ResponseEntity cancelShareVoucher(HttpServletRequest request, @PathVariable Long voucherId) { + String username = jwtProvider.getUsername(jwtProvider.resolveToken(request).substring(7)); + voucherService.cancelShare(username, voucherId); + return ResponseEntity.ok( + SuccessMessage.builder() + .path(request.getRequestURI()) + .build()); + } } \ No newline at end of file diff --git a/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherSaveService.java b/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherSaveService.java index 1f9d04b4..197458c3 100644 --- a/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherSaveService.java +++ b/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherSaveService.java @@ -83,17 +83,13 @@ public void execute(OCRDto ocrDto, String username) throws IOException { } public Mono handleGptResponse(OCRDto ocrDto, String username) throws IOException, GptResponseException { - return gptService.getGptResponse(ocrDto).flatMap(response -> { try { VoucherSaveRequestDto voucherSaveRequestDto = createVoucherSaveRequestDto(response); - System.out.println("GPT response"); - System.out.println(voucherSaveRequestDto.getBrandName()); - System.out.println(voucherSaveRequestDto.getProductName()); - System.out.println(voucherSaveRequestDto.getBarcode()); - System.out.println(voucherSaveRequestDto.getExpiresAt()); - if (voucherSaveRequestDto.getBrandName() == "" || voucherSaveRequestDto.getProductName() == "" - || voucherSaveRequestDto.getBarcode() == "" || voucherSaveRequestDto.getExpiresAt() == "") { + if (voucherSaveRequestDto.getBrandName() == "" || + voucherSaveRequestDto.getProductName() == "" || + voucherSaveRequestDto.getBarcode() == "" || + voucherSaveRequestDto.getExpiresAt() == "") { throw new GptResponseException("GPT 응답이 올바르지 않습니다.", StatusEnum.NOT_FOUND); } return Mono.just(voucherSaveRequestDto); diff --git a/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherService.java b/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherService.java index a277b2d3..cedadfa4 100644 --- a/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherService.java +++ b/src/main/java/org/swmaestro/repl/gifthub/vouchers/service/VoucherService.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Service; import org.swmaestro.repl.gifthub.auth.service.UserService; import org.swmaestro.repl.gifthub.exception.BusinessException; +import org.swmaestro.repl.gifthub.giftcard.entity.Giftcard; import org.swmaestro.repl.gifthub.giftcard.service.GiftcardService; import org.swmaestro.repl.gifthub.util.DateConverter; import org.swmaestro.repl.gifthub.util.StatusEnum; @@ -435,4 +436,23 @@ public VoucherShareResponseDto share(String username, Long voucherId, VoucherSha return giftCardService.create(voucher, voucherShareRequestDto.getMessage()); } + + /** + * 기프티콘 공유 취소 메서드 + */ + public Giftcard cancelShare(String username, Long voucherId) { + Voucher voucher = voucherRepository.findById(voucherId) + .orElseThrow(() -> new BusinessException("존재하지 않는 상품권 입니다.", StatusEnum.NOT_FOUND)); + + if (!voucher.getUser().getUsername().equals(username)) { + throw new BusinessException("상품권을 공유 취소할 권한이 없습니다.", StatusEnum.FORBIDDEN); + } + + Giftcard savedGiftcard = giftCardService.read(voucherId); + if (savedGiftcard == null) { + throw new BusinessException("존재하지 않는 공유 기프티콘 입니다.", StatusEnum.NOT_FOUND); + } + + return giftCardService.delete(savedGiftcard.getId()); + } } \ No newline at end of file diff --git a/src/test/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherControllerTest.java b/src/test/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherControllerTest.java index 390e9751..fbdd951b 100644 --- a/src/test/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherControllerTest.java +++ b/src/test/java/org/swmaestro/repl/gifthub/vouchers/controller/VoucherControllerTest.java @@ -15,6 +15,7 @@ import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; +import org.swmaestro.repl.gifthub.giftcard.entity.Giftcard; import org.swmaestro.repl.gifthub.giftcard.service.GiftcardService; import org.swmaestro.repl.gifthub.util.JwtProvider; import org.swmaestro.repl.gifthub.vouchers.dto.GptResponseDto; @@ -326,4 +327,32 @@ void shareVoucher() throws Exception { .andExpect(status().isOk()); } + /** + * 기프티콘 공유 취소 테스트 + */ + @Test + @WithMockUser(username = "이진우", roles = "USER") + void shareCancel() throws Exception { + //Given + Long voucherId = 1L; + VoucherShareRequestDto voucherShareRequestDto = VoucherShareRequestDto.builder() + .message("축하드립니다") + .build(); + VoucherShareResponseDto voucherShareResponseDto = VoucherShareResponseDto.builder() + .id("uuid") + .build(); + Giftcard giftcard = Giftcard.builder() + .id("uuid") + .build(); + //When + when(jwtProvider.resolveToken(any())).thenReturn("my_awesome_access_token"); + when(jwtProvider.getUsername(anyString())).thenReturn("이진우"); + when(voucherService.cancelShare(anyString(), eq(voucherId))).thenReturn(giftcard); + + //Then + mockMvc.perform(delete("/vouchers/1/share") + .header("Authorization", "my_awesome_access_token") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } } \ No newline at end of file