카드 매입 승인 경로 Spring Boot 3 전환 #1

Closed
forge-bot wants to merge 8 commits from forge/ACX-E2E-1785394564819-attempt-1-run-d41f8df477e9 into main
Showing only changes of commit 692278427d - Show all commits

View file

@ -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<ApprovalResponse> getPendingApprovals() {
return repository.findByStatus(ApprovalStatus.PENDING)
.stream()
.map(this::toResponse)
.collect(Collectors.toList());
}
@Transactional(readOnly = true)
public List<ApprovalResponse> 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()
);
}
}