3. 날짜 수정 후 부과 체크 - 명의이전 후 상품용인 경우 (31일 초과) 로직 추가

main
박성영 2 weeks ago
parent 65200c68c4
commit abaa4ed946

@ -94,7 +94,7 @@ public class ComparisonRemarkBuilder {
// 날짜 포맷 변환 (YYYYMMDD -> YY.M.D)
String chgYmdFormatted = DateUtil.formatToShortDate(ledgerRecord.getChgYmd());
String step1OwnerName = StringUtil.nvl(step1Record.getRprsOwnrNm());
String step1wnerName = StringUtil.nvl(step1Record.getRprsOwnrNm());
StringBuilder sb = new StringBuilder();
@ -124,6 +124,67 @@ public class ComparisonRemarkBuilder {
}
/**
* ( )
*
* :
* (25.9.3.)
* 222283
* -
*
*
*
*
* @param step1Record Step 1 API ( )
* @param step4Record Step 4 API ( = )
* @param ledgerRecord ( )
* @param vhclno
* @param inspYmd
* @param vldPrdExpryYmd
* @param inspEndYmd
* @param daysBetween
* @return
*/
public static String buildOwnerChangeRemark(NewBasicResponse.Record step1Record,
NewBasicResponse.Record step4Record,
NewLedgerResponse.Record ledgerRecord,
String vhclno,
String inspYmd,
String vldPrdExpryYmd,
String inspEndYmd,
long daysBetween) {
// 날짜 포맷 변환 (YYYYMMDD -> YY.M.D)
String chgYmdFormatted = DateUtil.formatToShortDate(ledgerRecord.getChgYmd());
String step1wnerName = StringUtil.nvl(step1Record.getRprsOwnrNm());
StringBuilder sb = new StringBuilder();
// 첫 줄: 명의이전(25.9.3.) 이전소유자 상품용
sb.append("명의이전(").append(chgYmdFormatted).append(")").append("\n");
// 둘째 줄: 차량번호
sb.append(StringUtil.nvl(vhclno)).append("\n");
// 셋째 줄: 검사기간 시작일자 - 종료일자
sb.append(" - 검사기간: ").append(DateUtil.formatDateString(vldPrdExpryYmd))
.append(" - ").append(DateUtil.formatDateString(inspEndYmd)).append("\n");
// 넷째 줄: 검사일 일자
sb.append(" - 검사일: ").append(DateUtil.formatDateString(inspYmd)).append("\n");
// 다섯째 줄: 명의이전 일자
sb.append(" - 명의이전: ").append(DateUtil.formatDateString(ledgerRecord.getChgYmd())).append("\n");
// 여섯째 줄: 상품용 일자 (명의이전 일자와 동일)
sb.append(" - 상품용: ").append(DateUtil.formatDateString(ledgerRecord.getChgYmd()));
// 일곱째 줄: 일수차이
sb.append("일수차이: ").append(daysBetween).append("일");
return sb.toString();
}
/**
*
*

@ -43,6 +43,12 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
/**
* ()
* ~ ,
*/
private static final int DAYS_THRESHOLD = 31;
/**
*
*
@ -147,17 +153,17 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
NewBasicResponse.Record step1Record = step1Response.getRecord().get(0);
String vin = step1Record.getVin(); // 차대번호
String step1OwnerName = step1Record.getRprsOwnrNm(); // 검사일 기준 소유자명
String step1wnerName = step1Record.getRprsOwnrNm(); // 검사일 기준 소유자명
log.info("[상품용] Step 1 결과 - 차대번호: {}, 소유자명: {}", vin, step1OwnerName);
log.info("[상품용] Step 1 결과 - 차대번호: {}, 소유자명: {}", vin, step1wnerName);
// 조건 1: 소유자명에 "상품용" 포함 여부 확인
if (step1OwnerName == null || !step1OwnerName.contains("상품용")) {
log.debug("[상품용] 소유자명에 '상품용' 미포함 - 차량번호: {}, 소유자명: {}", vhclno, step1OwnerName);
if (step1wnerName == null || !step1wnerName.contains("상품용")) {
log.debug("[상품용] 소유자명에 '상품용' 미포함 - 차량번호: {}, 소유자명: {}", vhclno, step1wnerName);
return null;
}
log.info("[상품용] 소유자명에 '상품용' 포함 확인! - 차량번호: {}, 소유자명: {}", vhclno, step1OwnerName);
log.info("[상품용] 소유자명에 '상품용' 포함 확인! - 차량번호: {}, 소유자명: {}", vhclno, step1wnerName);
// ========== Step 2: 자동차기본정보 조회 (차대번호, 부과일자=오늘일자) ==========
String today = LocalDate.now().format(DATE_FORMATTER);
@ -270,12 +276,12 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
log.info("[상품용] Step 4 결과 - 소유자명: {}", step4OwnerName);
// ========== 소유자명 비교 ==========
if (step4OwnerName == null || !step4OwnerName.equals(step1OwnerName)) {
log.debug("[상품용] 소유자명 불일치 - Step1 소유자명: {}, Step4 소유자명: {}", step1OwnerName, step4OwnerName);
if (step4OwnerName == null || !step4OwnerName.equals(step1wnerName)) {
log.debug("[상품용] 소유자명 불일치 - Step1 소유자명: {}, Step4 소유자명: {}", step1wnerName, step4OwnerName);
return null;
}
log.info("[상품용] 소유자명 일치 확인! - 소유자명: {}", step1OwnerName);
log.info("[상품용] 소유자명 일치 확인! - 소유자명: {}", step1wnerName);
// ========== 필요 없음.
// 어차피 상단에서 TB_CAR_FFNLG_TRGT.검사종료일자 작은것중의 마지막일자를 찾기때문에
@ -458,15 +464,15 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
return null;
}
// 조건: 가장 마지막 명의이전일자가 검사일의 31일 이내인지 확인
// 조건: 가장 마지막 명의이전일자가 검사일의 기준일수 이내인지 확인
long daysBetween = java.time.temporal.ChronoUnit.DAYS.between(latestChgDate, inspDate);
if (daysBetween < 0 || daysBetween > 31) {
log.debug("[내사종결] 명의이전일자가 검사일의 31일 이내가 아님 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
targetRecord.getChgYmd(), inspYmd, daysBetween);
if (daysBetween < 0 || daysBetween > DAYS_THRESHOLD) {
log.debug("[내사종결] 명의이전일자가 검사일의 {}일 이내가 아님 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetRecord.getChgYmd(), inspYmd, daysBetween);
return null;
}
log.info("[내사종결] 명의이전일자가 검사일의 31일 이내 확인 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
targetRecord.getChgYmd(), inspYmd, daysBetween);
log.info("[내사종결] 명의이전일자가 검사일의 {}일 이내 확인 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetRecord.getChgYmd(), inspYmd, daysBetween);
String targetChgYmd = targetRecord.getChgYmd();
log.info("[내사종결] 조건 충족 레코드 선택! 변경일자: {}, 변경업무: {}", targetChgYmd, targetRecord.getChgTaskSeNm());
@ -491,13 +497,11 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
log.info("[내사종결] Step 4 결과 - 소유자명: {}", step4OwnerName);
// ========== 소유자명 비교 - 상품용 포함 여부 확인 ==========
if (step4OwnerName == null || !step4OwnerName.contains("상품용")) {
log.debug("[내사종결] 소유자명에 '상품용' 포함 - Step4 소유자명: {}", step4OwnerName);
if (step4OwnerName == null || step4OwnerName.contains("상품용")) {
log.debug("[내사종결] 소유자명에 '상품용' 포함 - Step4 소유자명: {}", step4OwnerName);
return null;
}
log.info("[내사종결] 명의이전 시점 소유자명에 '상품용' 확인! - 소유자명: {}", step4OwnerName);
log.info("[내사종결] 모든 조건 충족! 차량번호: {}, 변경일자: {}", vhclno, targetChgYmd);
// ========== 비고 생성 ==========
@ -533,7 +537,211 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
}
/**
* 3. - , 31
* 3. - , 31
*
* API 3:
* 1) (, =) ,
* 2) (, =) , , ,
* 3) ()(, , , ) List
*
* :
* - 1: ( ~ ) ( 11)
* <= CHG_YMD <=
* CHG_TASK_SE_CD == "11" ()
* - 2:
* ~
* 31
*
* @param existingData
* @return 04 () null ()
*/
private String checkInvestigationClosedByOwnerChangeWithin31Days(CarFfnlgTrgtVO existingData) {
String vhclno = existingData.getVhclno();
String inspYmd = existingData.getInspYmd();
String vldPrdExpryYmd = existingData.getVldPrdExpryYmd();
String inspEndYmd = existingData.getInspEndYmd();
try {
// ========== Step 1: 자동차기본정보 조회 (차량번호, 부과일자=검사일) ==========
log.info("[내사종결-명의이전] Step 1: 자동차기본정보 조회 - 차량번호: {}, 검사일: {}", vhclno, inspYmd);
NewBasicRequest step1Request = createBasicRequest(vhclno, null, inspYmd);
NewBasicResponse step1Response = apiService.getBasicInfo(step1Request);
bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step1Response, existingData.getCarFfnlgTrgtId());
if (step1Response == null || step1Response.getRecord() == null || step1Response.getRecord().isEmpty()) {
log.warn("[내사종결-명의이전] Step 1 응답 없음 - 차량번호: {}", vhclno);
return null;
}
NewBasicResponse.Record step1Record = step1Response.getRecord().get(0);
String vin = step1Record.getVin(); // 차대번호
String step1OwnerName = step1Record.getRprsOwnrNm(); // 검사일 기준 소유자명
log.info("[내사종결-명의이전] Step 1 결과 - 차대번호: {}, 소유자명: {}", vin, step1OwnerName);
// 조건: 소유자명에 "상품용" 미포함 여부 확인 (명의이전 케이스는 상품용이 아니어야 함)
if (step1OwnerName != null && step1OwnerName.contains("상품용")) {
log.debug("[내사종결-명의이전] 소유자명에 '상품용' 포함 - 차량번호: {}, 소유자명: {}", vhclno, step1OwnerName);
return null;
}
log.info("[내사종결-명의이전] 소유자명에 '상품용' 미포함 확인 - 차량번호: {}, 소유자명: {}", vhclno, step1OwnerName);
// ========== Step 2: 자동차기본정보 조회 (차대번호, 부과일자=오늘일자) ==========
String today = LocalDate.now().format(DATE_FORMATTER);
log.info("[내사종결-명의이전] Step 2: 자동차기본정보 조회 - 차대번호: {}, 오늘일자: {}", vin, today);
NewBasicRequest step2Request = createBasicRequest(null, vin, today);
NewBasicResponse step2Response = apiService.getBasicInfo(step2Request);
bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step2Response, existingData.getCarFfnlgTrgtId());
if (step2Response == null || step2Response.getRecord() == null || step2Response.getRecord().isEmpty()) {
log.warn("[내사종결-명의이전] Step 2 응답 없음 - 차대번호: {}", vin);
return null;
}
NewBasicResponse.Record step2Record = step2Response.getRecord().get(0);
String currentVhclno = step2Record.getVhrno();
String currentOwnerName = step2Record.getRprsOwnrNm();
String currentIdecno = step2Record.getRprsvOwnrIdecno();
String currentLegalDongCode = step2Record.getUsgsrhldStdgCd();
log.info("[내사종결-명의이전] Step 2 결과 - 차량번호: {}, 성명: {}, 주민번호: {}, 법정동코드: {}",
currentVhclno, currentOwnerName, currentIdecno, currentLegalDongCode);
// ========== Step 3: 자동차등록원부(갑) 조회 ==========
log.info("[내사종결-명의이전] Step 3: 자동차등록원부(갑) 조회 - 차량번호: {}, 성명: {}, 주민번호: {}, 법정동코드: {}",
currentVhclno, currentOwnerName, currentIdecno, currentLegalDongCode);
NewLedgerRequest step3Request = createLedgerRequest(currentVhclno, currentOwnerName, currentIdecno, currentLegalDongCode);
NewLedgerResponse step3Response = apiService.getLedgerInfo(step3Request);
ledgerLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step3Response, existingData.getCarFfnlgTrgtId());
if (step3Response == null) {
log.warn("[내사종결-명의이전] Step 3 응답 없음 - 차량번호: {}", currentVhclno);
return null;
}
List<NewLedgerResponse.Record> ledgerRecords = step3Response.getRecord();
if (ledgerRecords == null || ledgerRecords.isEmpty()) {
log.debug("[내사종결-명의이전] 갑부 상세 내역 없음 - 차량번호: {}", vhclno);
return null;
}
// ========== 갑부 상세에서 검사기간 내 명의이전 레코드 찾기 ==========
log.info("[내사종결-명의이전] 갑부 상세 레코드 검색 시작 - 유효기간만료일: {}, 검사종료일자: {}", vldPrdExpryYmd, inspEndYmd);
NewLedgerResponse.Record targetRecord = null;
LocalDate vldPrdExpryDate = DateUtil.parseDate(vldPrdExpryYmd);
LocalDate inspEndDate = DateUtil.parseDate(inspEndYmd);
for (NewLedgerResponse.Record record : ledgerRecords) {
String chgYmd = record.getChgYmd();
String chgTaskSeCd = record.getChgTaskSeCd();
// 조건: CHG_TASK_SE_CD == "11" (명의이전)
if (!"11".equals(chgTaskSeCd) || chgYmd == null) {
continue;
}
LocalDate chgDate = DateUtil.parseDate(chgYmd);
if (chgDate == null) {
continue;
}
// 조건: 유효기간만료일 <= CHG_YMD <= 검사종료일자
if ((chgDate.isEqual(vldPrdExpryDate) || chgDate.isAfter(vldPrdExpryDate)) &&
(chgDate.isEqual(inspEndDate) || chgDate.isBefore(inspEndDate))) {
targetRecord = record;
log.debug("[내사종결-명의이전] 검사기간 내 명의이전 발견 - 변경일자: {}, 변경업무: {}", chgYmd, chgTaskSeCd);
break; // 첫 번째 발견된 명의이전 사용
}
}
if (targetRecord == null) {
log.debug("[내사종결-명의이전] 검사기간 내 명의이전 레코드 없음 - 차량번호: {}", vhclno);
return null;
}
String targetChgYmd = targetRecord.getChgYmd();
log.info("[내사종결-명의이전] 검사기간 내 명의이전 발견! 변경일자: {}, 변경업무: {}", targetChgYmd, targetRecord.getChgTaskSeNm());
// ========== 명의이전일자 ~ 검사일 사이의 일수 계산 ==========
LocalDate chgDate = DateUtil.parseDate(targetChgYmd);
LocalDate inspDate = DateUtil.parseDate(inspYmd);
long daysBetween = java.time.temporal.ChronoUnit.DAYS.between(chgDate, inspDate);
if (daysBetween < 0 || daysBetween > DAYS_THRESHOLD) {
log.debug("[내사종결-명의이전] 명의이전일자가 검사일의 {}일 이내가 아님 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetChgYmd, inspYmd, daysBetween);
return null;
}
log.info("[내사종결-명의이전] 명의이전일자가 검사일의 {}일 이내 확인 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetChgYmd, inspYmd, daysBetween);
// ========== Step 4: 자동차기본정보 조회 (차대번호, 부과일자=CHG_YMD -1일) ==========
LocalDate targetDate = DateUtil.parseDate(targetChgYmd);
String targetChgYmdMinus1 = targetDate.minusDays(1).format(DATE_FORMATTER);
log.info("[내사종결-명의이전] Step 4: 자동차기본정보 조회 - 차대번호: {}, 부과일자: {} (원본: {})", vin, targetChgYmdMinus1, targetChgYmd);
NewBasicRequest step4Request = createBasicRequest(null, vin, targetChgYmdMinus1);
NewBasicResponse step4Response = apiService.getBasicInfo(step4Request);
bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step4Response, existingData.getCarFfnlgTrgtId());
if (step4Response == null || step4Response.getRecord() == null || step4Response.getRecord().isEmpty()) {
log.warn("[내사종결-명의이전] Step 4 응답 없음 - 차대번호: {}, 부과일자: {}", vin, targetChgYmdMinus1);
return null;
}
NewBasicResponse.Record step4Record = step4Response.getRecord().get(0);
String step4OwnerName = step4Record.getRprsOwnrNm(); // CHG_YMD 시점의 소유자명
log.info("[내사종결-명의이전] Step 4 결과 - 소유자명: {}", step4OwnerName);
// ========== 소유자명 비교 - 명의이전 전 소유자가 상품용이어야 함 ==========
if (step4OwnerName == null || !step4OwnerName.contains("상품용")) {
log.debug("[내사종결-명의이전] 명의이전 전 소유자명에 '상품용' 미포함 - Step4 소유자명: {}", step4OwnerName);
return null;
}
log.info("[내사종결-명의이전] 명의이전 - 소유자명: {}", step4OwnerName);
// ========== 비고 생성 ==========
String rmrk = ComparisonRemarkBuilder.buildOwnerChangeRemark(
step1Record, step4Record, targetRecord,
vhclno, inspYmd, vldPrdExpryYmd, inspEndYmd, daysBetween
);
// ========== DB 업데이트 ==========
existingData.setCarBassMatterInqireId(step1Response.getGeneratedId());
existingData.setCarLedgerFrmbkId(step3Response.getGeneratedId());
existingData.setTaskPrcsSttsCd(TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_04_INVESTIGATION_CLOSED);
existingData.setTaskPrcsYmd(LocalDate.now().format(DATE_FORMATTER));
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd(targetRecord.getChgTaskSeCd());
existingData.setCarRegFrmbkChgTaskSeNm(targetRecord.getChgTaskSeNm());
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd().replace("-", ""));
existingData.setCarRegFrmbkDtl(ComparisonRemarkBuilder.buildLedgerRecordDetail(targetRecord));
existingData.setRmrk(rmrk);
int updateCount = carFfnlgTrgtMapper.update(existingData);
if (updateCount == 0) {
throw new MessageException(String.format("[내사종결-명의이전] 업데이트 실패: %s", vhclno));
}
log.info("[내사종결-명의이전] 처리 완료! 차량번호: {}", vhclno);
return TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_04_INVESTIGATION_CLOSED;
} catch (Exception e) {
log.error("[내사종결-명의이전] 검증 중 오류 발생 - 차량번호: {}", vhclno, e);
throw new MessageException(String.format("[내사종결-명의이전] 검증 중 오류 발생 - 차량번호: %s", vhclno), e);
}
}
/**
* 4. - , 31
*
* API 4:
* 1) (, =) ,
@ -668,15 +876,15 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
return null;
}
// 조건: 가장 마지막 명의이전일자가 검사일의 31일 초과인지 확인
// 조건: 가장 마지막 명의이전일자가 검사일의 기준일수 초과인지 확인
long daysBetween = java.time.temporal.ChronoUnit.DAYS.between(latestChgDate, inspDate);
if (daysBetween <= 31) {
log.debug("[날짜수정후부과] 명의이전일자가 검사일의 31일 이내임 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
targetRecord.getChgYmd(), inspYmd, daysBetween);
if (daysBetween <= DAYS_THRESHOLD) {
log.debug("[날짜수정후부과] 명의이전일자가 검사일의 {}일 이내임 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetRecord.getChgYmd(), inspYmd, daysBetween);
return null;
}
log.info("[날짜수정후부과] 명의이전일자가 검사일의 31일 초과 확인 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
targetRecord.getChgYmd(), inspYmd, daysBetween);
log.info("[날짜수정후부과] 명의이전일자가 검사일의 {}일 초과 확인 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetRecord.getChgYmd(), inspYmd, daysBetween);
String targetChgYmd = targetRecord.getChgYmd();
log.info("[날짜수정후부과] 조건 충족 레코드 선택! 변경일자: {}, 변경업무: {}", targetChgYmd, targetRecord.getChgTaskSeNm());
@ -742,9 +950,213 @@ public class ComparisonServiceImpl extends EgovAbstractServiceImpl implements Co
}
}
/**
* 5. - , 31
*
* API 3:
* 1) (, =) ,
* 2) (, =) , , ,
* 3) ()(, , , ) List
*
* :
* - 1: ( ~ ) ( 11)
* <= CHG_YMD <=
* CHG_TASK_SE_CD == "11" ()
* - 2:
* ~
* 31
*
* @param existingData
* @return 05 ( ) null ()
*/
private String checkDateModifiedLevyByOwnerChangeOver31Days(CarFfnlgTrgtVO existingData) {
String vhclno = existingData.getVhclno();
String inspYmd = existingData.getInspYmd();
String vldPrdExpryYmd = existingData.getVldPrdExpryYmd();
String inspEndYmd = existingData.getInspEndYmd();
try {
// ========== Step 1: 자동차기본정보 조회 (차량번호, 부과일자=검사일) ==========
log.info("[날짜수정후부과-명의이전] Step 1: 자동차기본정보 조회 - 차량번호: {}, 검사일: {}", vhclno, inspYmd);
NewBasicRequest step1Request = createBasicRequest(vhclno, null, inspYmd);
NewBasicResponse step1Response = apiService.getBasicInfo(step1Request);
bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step1Response, existingData.getCarFfnlgTrgtId());
if (step1Response == null || step1Response.getRecord() == null || step1Response.getRecord().isEmpty()) {
log.warn("[날짜수정후부과-명의이전] Step 1 응답 없음 - 차량번호: {}", vhclno);
return null;
}
NewBasicResponse.Record step1Record = step1Response.getRecord().get(0);
String vin = step1Record.getVin(); // 차대번호
String step1OwnerName = step1Record.getRprsOwnrNm(); // 검사일 기준 소유자명
log.info("[날짜수정후부과-명의이전] Step 1 결과 - 차대번호: {}, 소유자명: {}", vin, step1OwnerName);
// 조건: 소유자명에 "상품용" 미포함 여부 확인 (명의이전 케이스는 상품용이 아니어야 함)
if (step1OwnerName != null && step1OwnerName.contains("상품용")) {
log.debug("[날짜수정후부과-명의이전] 소유자명에 '상품용' 포함 - 차량번호: {}, 소유자명: {}", vhclno, step1OwnerName);
return null;
}
log.info("[날짜수정후부과-명의이전] 소유자명에 '상품용' 미포함 확인 - 차량번호: {}, 소유자명: {}", vhclno, step1OwnerName);
// ========== Step 2: 자동차기본정보 조회 (차대번호, 부과일자=오늘일자) ==========
String today = LocalDate.now().format(DATE_FORMATTER);
log.info("[날짜수정후부과-명의이전] Step 2: 자동차기본정보 조회 - 차대번호: {}, 오늘일자: {}", vin, today);
NewBasicRequest step2Request = createBasicRequest(null, vin, today);
NewBasicResponse step2Response = apiService.getBasicInfo(step2Request);
bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step2Response, existingData.getCarFfnlgTrgtId());
if (step2Response == null || step2Response.getRecord() == null || step2Response.getRecord().isEmpty()) {
log.warn("[날짜수정후부과-명의이전] Step 2 응답 없음 - 차대번호: {}", vin);
return null;
}
NewBasicResponse.Record step2Record = step2Response.getRecord().get(0);
String currentVhclno = step2Record.getVhrno();
String currentOwnerName = step2Record.getRprsOwnrNm();
String currentIdecno = step2Record.getRprsvOwnrIdecno();
String currentLegalDongCode = step2Record.getUsgsrhldStdgCd();
log.info("[날짜수정후부과-명의이전] Step 2 결과 - 차량번호: {}, 성명: {}, 주민번호: {}, 법정동코드: {}",
currentVhclno, currentOwnerName, currentIdecno, currentLegalDongCode);
// ========== Step 3: 자동차등록원부(갑) 조회 ==========
log.info("[날짜수정후부과-명의이전] Step 3: 자동차등록원부(갑) 조회 - 차량번호: {}, 성명: {}, 주민번호: {}, 법정동코드: {}",
currentVhclno, currentOwnerName, currentIdecno, currentLegalDongCode);
NewLedgerRequest step3Request = createLedgerRequest(currentVhclno, currentOwnerName, currentIdecno, currentLegalDongCode);
NewLedgerResponse step3Response = apiService.getLedgerInfo(step3Request);
ledgerLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step3Response, existingData.getCarFfnlgTrgtId());
if (step3Response == null) {
log.warn("[날짜수정후부과-명의이전] Step 3 응답 없음 - 차량번호: {}", currentVhclno);
return null;
}
List<NewLedgerResponse.Record> ledgerRecords = step3Response.getRecord();
if (ledgerRecords == null || ledgerRecords.isEmpty()) {
log.debug("[날짜수정후부과-명의이전] 갑부 상세 내역 없음 - 차량번호: {}", vhclno);
return null;
}
// ========== 갑부 상세에서 검사기간 내 명의이전 레코드 찾기 ==========
log.info("[날짜수정후부과-명의이전] 갑부 상세 레코드 검색 시작 - 유효기간만료일: {}, 검사종료일자: {}", vldPrdExpryYmd, inspEndYmd);
NewLedgerResponse.Record targetRecord = null;
LocalDate vldPrdExpryDate = DateUtil.parseDate(vldPrdExpryYmd);
LocalDate inspEndDate = DateUtil.parseDate(inspEndYmd);
for (NewLedgerResponse.Record record : ledgerRecords) {
String chgYmd = record.getChgYmd();
String chgTaskSeCd = record.getChgTaskSeCd();
// 조건: CHG_TASK_SE_CD == "11" (명의이전)
if (!"11".equals(chgTaskSeCd) || chgYmd == null) {
continue;
}
LocalDate chgDate = DateUtil.parseDate(chgYmd);
if (chgDate == null) {
continue;
}
// 조건: 유효기간만료일 <= CHG_YMD <= 검사종료일자
if ((chgDate.isEqual(vldPrdExpryDate) || chgDate.isAfter(vldPrdExpryDate)) &&
(chgDate.isEqual(inspEndDate) || chgDate.isBefore(inspEndDate))) {
targetRecord = record;
log.debug("[날짜수정후부과-명의이전] 검사기간 내 명의이전 발견 - 변경일자: {}, 변경업무: {}", chgYmd, chgTaskSeCd);
break; // 첫 번째 발견된 명의이전 사용
}
}
if (targetRecord == null) {
log.debug("[날짜수정후부과-명의이전] 검사기간 내 명의이전 레코드 없음 - 차량번호: {}", vhclno);
return null;
}
String targetChgYmd = targetRecord.getChgYmd();
log.info("[날짜수정후부과-명의이전] 검사기간 내 명의이전 발견! 변경일자: {}, 변경업무: {}", targetChgYmd, targetRecord.getChgTaskSeNm());
// ========== 명의이전일자 ~ 검사일 사이의 일수 계산 ==========
LocalDate chgDate = DateUtil.parseDate(targetChgYmd);
LocalDate inspDate = DateUtil.parseDate(inspYmd);
long daysBetween = java.time.temporal.ChronoUnit.DAYS.between(chgDate, inspDate);
if (daysBetween <= DAYS_THRESHOLD) {
log.debug("[날짜수정후부과-명의이전] 명의이전일자가 검사일의 {}일 이내임 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetChgYmd, inspYmd, daysBetween);
return null;
}
log.info("[날짜수정후부과-명의이전] 명의이전일자가 검사일의 {}일 초과 확인 - 변경일자: {}, 검사일: {}, 일수차이: {}일",
DAYS_THRESHOLD, targetChgYmd, inspYmd, daysBetween);
// ========== Step 4: 자동차기본정보 조회 (차대번호, 부과일자=CHG_YMD -1일) ==========
LocalDate targetDate = DateUtil.parseDate(targetChgYmd);
String targetChgYmdMinus1 = targetDate.minusDays(1).format(DATE_FORMATTER);
log.info("[날짜수정후부과-명의이전] Step 4: 자동차기본정보 조회 - 차대번호: {}, 부과일자: {} (원본: {})", vin, targetChgYmdMinus1, targetChgYmd);
NewBasicRequest step4Request = createBasicRequest(null, vin, targetChgYmdMinus1);
NewBasicResponse step4Response = apiService.getBasicInfo(step4Request);
bassMatterLogService.updateCarFfnlgTrgtIdByTxIdNewTx(step4Response, existingData.getCarFfnlgTrgtId());
if (step4Response == null || step4Response.getRecord() == null || step4Response.getRecord().isEmpty()) {
log.warn("[날짜수정후부과-명의이전] Step 4 응답 없음 - 차대번호: {}, 부과일자: {}", vin, targetChgYmdMinus1);
return null;
}
NewBasicResponse.Record step4Record = step4Response.getRecord().get(0);
String step4OwnerName = step4Record.getRprsOwnrNm(); // CHG_YMD 시점의 소유자명
log.info("[날짜수정후부과-명의이전] Step 4 결과 - 소유자명: {}", step4OwnerName);
// ========== 소유자명 비교 - 명의이전 전 소유자가 상품용이어야 함 ==========
if (step4OwnerName == null || step4OwnerName.contains("상품용")) {
log.debug("[날짜수정후부과-명의이전] 명의이전 전 소유자명에 '상품용' 포함 - Step4 소유자명: {}", step4OwnerName);
return null;
}
log.info("[날짜수정후부과-명의이전] 명의이전 - 소유자명: {}", step4OwnerName);
// ========== 비고 생성 ==========
String rmrk = ComparisonRemarkBuilder.buildOwnerChangeRemark(
step1Record, step4Record, targetRecord,
vhclno, inspYmd, vldPrdExpryYmd, inspEndYmd, daysBetween
);
// ========== DB 업데이트 ==========
existingData.setCarBassMatterInqireId(step1Response.getGeneratedId());
existingData.setCarLedgerFrmbkId(step3Response.getGeneratedId());
existingData.setTaskPrcsSttsCd(TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_05_DATE_MODIFIED_LEVY);
existingData.setTaskPrcsYmd(LocalDate.now().format(DATE_FORMATTER));
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd(targetRecord.getChgTaskSeCd());
existingData.setCarRegFrmbkChgTaskSeNm(targetRecord.getChgTaskSeNm());
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd().replace("-", ""));
existingData.setCarRegFrmbkDtl(ComparisonRemarkBuilder.buildLedgerRecordDetail(targetRecord));
existingData.setRmrk(rmrk);
int updateCount = carFfnlgTrgtMapper.update(existingData);
if (updateCount == 0) {
throw new MessageException(String.format("[날짜수정후부과-명의이전] 업데이트 실패: %s", vhclno));
}
log.info("[날짜수정후부과-명의이전] 처리 완료! 차량번호: {}", vhclno);
return TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_05_DATE_MODIFIED_LEVY;
} catch (Exception e) {
log.error("[날짜수정후부과-명의이전] 검증 중 오류 발생 - 차량번호: {}", vhclno, e);
throw new MessageException(String.format("[날짜수정후부과-명의이전] 검증 중 오류 발생 - 차량번호: %s", vhclno), e);
}
}
/**
* 4.
* 6.
*
* DAYCNT :
* - DAYCNT > 115: -2 ( = + 115)

Loading…
Cancel
Save