From 692278427d756c72058648ba7dd73e4d76ac77d4 Mon Sep 17 00:00:00 2001 From: forge-bot Date: Thu, 30 Jul 2026 07:29:35 +0000 Subject: [PATCH] =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=EB=A7=A4=EC=9E=85=20?= =?UTF-8?q?=EC=8A=B9=EC=9D=B8=20=EA=B2=BD=EB=A1=9C=20Spring=20Boot=203=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20(ACX-E2E-1785394564819)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/AcquisitionApprovalService.java | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/main/java/com/acquirex/service/AcquisitionApprovalService.java diff --git a/src/main/java/com/acquirex/service/AcquisitionApprovalService.java b/src/main/java/com/acquirex/service/AcquisitionApprovalService.java new file mode 100644 index 0000000..6d47d2e --- /dev/null +++ b/src/main/java/com/acquirex/service/AcquisitionApprovalService.java @@ -0,0 +1,125 @@ +package com.acquirex.service; + +import com.acquirex.domain.AcquisitionApproval; +import com.acquirex.domain.AcquisitionApproval.ApprovalStatus; +import com.acquirex.dto.ApprovalRequest; +import com.acquirex.dto.ApprovalResponse; +import com.acquirex.exception.ApprovalProcessingException; +import com.acquirex.repository.AcquisitionApprovalRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +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) { + validateRequest(request); + + AcquisitionApproval approval = new AcquisitionApproval(); + approval.setMerchantId(request.getMerchantId()); + approval.setCardNumber(maskCardNumber(request.getCardNumber())); + approval.setAmount(request.getAmount()); + approval.setCurrency(request.getCurrency()); + + AcquisitionApproval saved = repository.save(approval); + return toResponse(saved); + } + + @Transactional + public ApprovalResponse processApproval(Long id, boolean approved, String reason) { + AcquisitionApproval approval = repository.findById(id) + .orElseThrow(() -> new ApprovalProcessingException("Approval not found: " + id)); + + if (approval.getStatus() != ApprovalStatus.PENDING) { + throw new ApprovalProcessingException("Approval already processed"); + } + + if (approved) { + approval.setStatus(ApprovalStatus.APPROVED); + approval.setApprovalCode(generateApprovalCode()); + } else { + approval.setStatus(ApprovalStatus.REJECTED); + approval.setRejectionReason(reason); + } + approval.setProcessedAt(LocalDateTime.now()); + + AcquisitionApproval saved = repository.save(approval); + return toResponse(saved); + } + + @Transactional(readOnly = true) + public ApprovalResponse getApproval(Long id) { + return repository.findById(id) + .map(this::toResponse) + .orElseThrow(() -> new ApprovalProcessingException("Approval not found: " + id)); + } + + @Transactional(readOnly = true) + public List getPendingApprovals() { + return repository.findByStatus(ApprovalStatus.PENDING) + .stream() + .map(this::toResponse) + .collect(Collectors.toList()); + } + + @Transactional(readOnly = true) + public List getApprovalsByMerchant(String merchantId) { + return repository.findByMerchantId(merchantId) + .stream() + .map(this::toResponse) + .collect(Collectors.toList()); + } + + private void validateRequest(ApprovalRequest request) { + if (request.getMerchantId() == null || request.getMerchantId().isBlank()) { + throw new ApprovalProcessingException("Merchant ID is required"); + } + if (request.getCardNumber() == null || request.getCardNumber().length() < 13) { + throw new ApprovalProcessingException("Valid card number is required"); + } + if (request.getAmount() == null || request.getAmount().compareTo(java.math.BigDecimal.ZERO) <= 0) { + throw new ApprovalProcessingException("Amount must be positive"); + } + if (request.getCurrency() == null || request.getCurrency().length() != 3) { + throw new ApprovalProcessingException("Valid currency code is required"); + } + } + + private String maskCardNumber(String cardNumber) { + if (cardNumber == null || cardNumber.length() < 4) { + return "****"; + } + return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4); + } + + private String generateApprovalCode() { + return "APP-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase(); + } + + private ApprovalResponse toResponse(AcquisitionApproval approval) { + return new ApprovalResponse( + approval.getId(), + approval.getMerchantId(), + approval.getCardNumber(), + approval.getAmount(), + approval.getCurrency(), + approval.getStatus().name(), + approval.getApprovalCode(), + approval.getRejectionReason(), + approval.getRequestedAt(), + approval.getProcessedAt() + ); + } +} \ No newline at end of file