diff --git a/src/main/java/com/acquirex/cardacquisition/service/AcquisitionApprovalService.java b/src/main/java/com/acquirex/cardacquisition/service/AcquisitionApprovalService.java new file mode 100644 index 0000000..0ca5b5e --- /dev/null +++ b/src/main/java/com/acquirex/cardacquisition/service/AcquisitionApprovalService.java @@ -0,0 +1,100 @@ +package com.acquirex.cardacquisition.service; + +import com.acquirex.cardacquisition.domain.AcquisitionApproval; +import com.acquirex.cardacquisition.domain.AcquisitionApproval.ApprovalStatus; +import com.acquirex.cardacquisition.dto.ApprovalDto.ApprovalRequest; +import com.acquirex.cardacquisition.dto.ApprovalDto.ApprovalResponse; +import com.acquirex.cardacquisition.repository.AcquisitionApprovalRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Service +public class AcquisitionApprovalService { + + private final AcquisitionApprovalRepository repository; + + public AcquisitionApprovalService(AcquisitionApprovalRepository repository) { + this.repository = repository; + } + + @Transactional + public ApprovalResponse requestApproval(ApprovalRequest request) { + AcquisitionApproval approval = new AcquisitionApproval(); + approval.setCardNumber(request.cardNumber()); + approval.setMerchantId(request.merchantId()); + approval.setAmount(request.amount()); + approval.setStatus(ApprovalStatus.PENDING); + + AcquisitionApproval saved = repository.save(approval); + return toResponse(saved); + } + + @Transactional + public ApprovalResponse approve(Long id) { + AcquisitionApproval approval = repository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("승인 요청을 찾을 수 없습니다: " + id)); + + if (approval.getStatus() != ApprovalStatus.PENDING) { + throw new IllegalStateException("대기 상태의 요청만 승인 가능합니다"); + } + + approval.setStatus(ApprovalStatus.APPROVED); + approval.setApprovalCode(generateApprovalCode()); + + AcquisitionApproval saved = repository.save(approval); + return toResponse(saved); + } + + @Transactional + public ApprovalResponse reject(Long id) { + AcquisitionApproval approval = repository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("승인 요청을 찾을 수 없습니다: " + id)); + + if (approval.getStatus() != ApprovalStatus.PENDING) { + throw new IllegalStateException("대기 상태의 요청만 거절 가능합니다"); + } + + approval.setStatus(ApprovalStatus.REJECTED); + + AcquisitionApproval saved = repository.save(approval); + return toResponse(saved); + } + + @Transactional(readOnly = true) + public List getPendingApprovals() { + return repository.findByStatus(ApprovalStatus.PENDING) + .stream().map(this::toResponse).collect(Collectors.toList()); + } + + @Transactional(readOnly = true) + public ApprovalResponse getApproval(Long id) { + return repository.findById(id) + .map(this::toResponse) + .orElseThrow(() -> new IllegalArgumentException("승인 요청을 찾을 수 없습니다: " + id)); + } + + private String generateApprovalCode() { + return "APX" + UUID.randomUUID().toString().substring(0, 8).toUpperCase(); + } + + private ApprovalResponse toResponse(AcquisitionApproval approval) { + return new ApprovalResponse( + approval.getId(), + maskCardNumber(approval.getCardNumber()), + approval.getMerchantId(), + approval.getAmount(), + approval.getStatus(), + approval.getApprovalCode(), + approval.getCreatedAt() + ); + } + + private String maskCardNumber(String cardNumber) { + if (cardNumber == null || cardNumber.length() < 4) return cardNumber; + return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4); + } +} \ No newline at end of file