diff --git a/src/main/java/com/acquirex/service/ApprovalService.java b/src/main/java/com/acquirex/service/ApprovalService.java new file mode 100644 index 0000000..3dffa02 --- /dev/null +++ b/src/main/java/com/acquirex/service/ApprovalService.java @@ -0,0 +1,110 @@ +package com.acquirex.service; + +import com.acquirex.domain.AcquisitionCard; +import com.acquirex.domain.ApprovalRequest; +import com.acquirex.dto.ApprovalRequestDto; +import com.acquirex.dto.ApprovalResponseDto; +import com.acquirex.repository.AcquisitionCardRepository; +import com.acquirex.repository.ApprovalRequestRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Service +public class ApprovalService { + + private final ApprovalRequestRepository approvalRequestRepository; + private final AcquisitionCardRepository acquisitionCardRepository; + + public ApprovalService(ApprovalRequestRepository approvalRequestRepository, + AcquisitionCardRepository acquisitionCardRepository) { + this.approvalRequestRepository = approvalRequestRepository; + this.acquisitionCardRepository = acquisitionCardRepository; + } + + @Transactional + public ApprovalResponseDto requestApproval(ApprovalRequestDto dto) { + String transactionId = generateTransactionId(); + + AcquisitionCard card = acquisitionCardRepository + .findByCardNumberAndCardCompanyCode(dto.getCardNumber(), dto.getCardCompanyCode()) + .orElseGet(() -> createNewCard(dto)); + + ApprovalRequest request = new ApprovalRequest(); + request.setCardId(card.getId()); + request.setTransactionId(transactionId); + request.setAmount(dto.getAmount()); + request.setVat(dto.getVat()); + request.setApprovalStatus(ApprovalRequest.ApprovalStatus.REQUESTED); + + ApprovalRequest saved = approvalRequestRepository.save(request); + return buildApprovalResponse(saved, "매입 승인 요청이 완료되었습니다"); + } + + @Transactional + public ApprovalResponseDto approveRequest(Long requestId) { + ApprovalRequest request = approvalRequestRepository.findById(requestId) + .orElseThrow(() -> new IllegalArgumentException("승인 요청을 찾을 수 없습니다: " + requestId)); + + if (request.getApprovalStatus() != ApprovalRequest.ApprovalStatus.REQUESTED) { + throw new IllegalStateException("이미 처리된 요청입니다"); + } + + request.setApprovalNumber(generateApprovalNumber()); + request.setApprovalStatus(ApprovalRequest.ApprovalStatus.APPROVED); + request.setApprovedAt(LocalDateTime.now()); + + ApprovalRequest saved = approvalRequestRepository.save(request); + return buildApprovalResponse(saved, "매입 승인이 완료되었습니다"); + } + + @Transactional + public ApprovalResponseDto rejectRequest(Long requestId, String reason) { + ApprovalRequest request = approvalRequestRepository.findById(requestId) + .orElseThrow(() -> new IllegalArgumentException("승인 요청을 찾을 수 없습니다: " + requestId)); + + if (request.getApprovalStatus() != ApprovalRequest.ApprovalStatus.REQUESTED) { + throw new IllegalStateException("이미 처리된 요청입니다"); + } + + request.setApprovalStatus(ApprovalRequest.ApprovalStatus.REJECTED); + request.setRejectionReason(reason); + + ApprovalRequest saved = approvalRequestRepository.save(request); + return buildApprovalResponse(saved, "매입 승인이 거절되었습니다"); + } + + @Transactional(readOnly = true) + public ApprovalResponseDto getApprovalStatus(Long requestId) { + ApprovalRequest request = approvalRequestRepository.findById(requestId) + .orElseThrow(() -> new IllegalArgumentException("승인 요청을 찾을 수 없습니다: " + requestId)); + return buildApprovalResponse(request, "조회가 완료되었습니다"); + } + + private AcquisitionCard createNewCard(ApprovalRequestDto dto) { + AcquisitionCard card = new AcquisitionCard(); + card.setCardNumber(dto.getCardNumber()); + card.setCardCompanyCode(dto.getCardCompanyCode()); + card.setMerchantNumber(dto.getMerchantNumber()); + card.setStatus(AcquisitionCard.CardStatus.PENDING); + return acquisitionCardRepository.save(card); + } + + private String generateTransactionId() { + return "TX" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase(); + } + + private String generateApprovalNumber() { + return "AP" + System.currentTimeMillis(); + } + + private ApprovalResponseDto buildApprovalResponse(ApprovalRequest request, String message) { + return new ApprovalResponseDto( + request.getId(), request.getTransactionId(), request.getApprovalNumber(), + request.getApprovalStatus().name(), request.getAmount(), request.getVat(), + request.getApprovedAt(), message + ); + } +} \ No newline at end of file