package com.snp.batch.service; import com.snp.batch.global.model.BatchLastExecution; import com.snp.batch.global.repository.BatchLastExecutionRepository; import jakarta.transaction.Transactional; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.*; @Service public class BatchDateService { private final BatchLastExecutionRepository repository; public BatchDateService(BatchLastExecutionRepository repository) { this.repository = repository; } /** * API 호출에 필요한 from/to 날짜 파라미터를 계산하고 반환합니다. */ public Map getShipUpdateApiDateParams(String apiKey) { // 1. 마지막 성공 일자 (FROM 날짜)를 DB에서 조회 // 조회된 값이 없으면 (최초 실행), API 호출 시점의 하루 전 날짜를 사용합니다. LocalDate lastDate = repository.findLastSuccessDate(apiKey) .orElse(LocalDate.now().minusDays(1)); // 2. 현재 실행 시점의 일자 (TO 날짜) 계산 LocalDate currentDate = LocalDate.now(); // 3. 파라미터 Map 구성 Map params = new HashMap<>(); // FROM Parameters (DB 조회 값) params.put("fromYear", String.valueOf(lastDate.getYear())); params.put("fromMonth", String.valueOf(lastDate.getMonthValue())); params.put("fromDay", String.valueOf(lastDate.getDayOfMonth())); // TO Parameters (현재 시점 값) params.put("toYear", String.valueOf(currentDate.getYear())); params.put("toMonth", String.valueOf(currentDate.getMonthValue())); params.put("toDay", String.valueOf(currentDate.getDayOfMonth())); // 고정 값 params.put("shipsCategory", "0"); return params; } public Map getRiskComplianceApiDateParams(String apiKey) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SS'Z'"); // 1. 마지막 성공 일자 (FROM 날짜)를 DB에서 조회 // 조회된 값이 없으면 (최초 실행), API 호출 시점의 하루 전 날짜를 사용합니다. LocalDate lastDate = repository.findLastSuccessDate(apiKey) .orElse(LocalDate.now().minusDays(1)); // 2. 현재 실행 시점의 일자 (TO 날짜) 계산 ZonedDateTime nowUtc = ZonedDateTime.now(ZoneOffset.UTC); // 3. 파라미터 Map 구성 Map params = new HashMap<>(); // FROM Parameters (DB 조회 값) String fromDateStr = lastDate.atStartOfDay().format(formatter); params.put("fromDate", fromDateStr); // TO Parameters (현재 시점 값) String toDateStr = nowUtc.format(formatter); params.put("toDate", toDateStr); return params; } /** * 배치 성공 시, 다음 실행을 위해 to 날짜를 DB에 저장 및 업데이트합니다. * @param successDate API 호출 성공 시 사용된 to 날짜 */ @Transactional // UPDATE 쿼리를 사용하므로 트랜잭션 필요 public void updateLastSuccessDate(String apiKey, LocalDate successDate) { // ✨ apiKey 추가 // 1. UPDATE 시도 int updatedRows = repository.updateLastSuccessDate(apiKey, successDate); // 2. 업데이트된 레코드가 없다면 (최초 실행), INSERT 수행 if (updatedRows == 0) { BatchLastExecution entity = new BatchLastExecution(apiKey, successDate); repository.save(entity); } } }