9.1 KiB
자동차 과태료 비교 로직 명세서
개요
자동차 과태료 부과 대상을 검증하기 위한 비교 로직 정의서입니다. CarFfnlgTrgtServiceImpl.compareWithApi 메소드안에 해당 로직이 들어가야함 기존에 사용하던 비교로직 서비스 : src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/ComparisonServiceImpl.java 그러나 이젠 아예 비교로직이 틀어져서 compareWithApi 메소드 포함, ComparisonServiceImpl 서비스 자체를 처음부터 다시 개발해도 무방. 기존꺼 활용하기보다는 아예 재구축 검토
기본 설정
- 비교로직에 사용되는 API는 ExternalVehicleApiServiceImpl.getBasicInfo, getLedgerInfo 호출!!
처리 규칙
중요: 순서가 중요함!
- 조건에 걸리는 순간 다음 차량번호 비교로 진행
- 각 비교 로직별로 개별 API 호출 수행
비교 로직 상세
1. 상품용 검증
필요 API: 자동차등록원부(갑)
API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 |
|---|---|---|---|
| 1 | 자동차기본정보 | 차량번호, 부과일자=검사일 |
차대번호, 소유자명 |
| 2 | 자동차기본정보 | 1.차대번호, 부과일자=오늘일자 |
차량번호, 성명, 민원인주민번호, 민원인법정동코드 |
| 3 | 자동차등록원본(갑) | 2.차량번호, 2.성명, 2.민원인주민번호, 2.민원인법정동코드 |
갑부 상세 List |
비교 조건
// 조건 1: 소유자명에 '상품용' 포함 여부
api-1번호출.소유자명.contains("상품용")
// 조건 2: 갑부 상세 목록에서 명의이전 이력 확인
for (LedgerRecord record : 갑부상세List) {
if (record.CHG_YMD >= TB_CAR_FFNLG_TRGT.유효기간만료일
&& record.CHG_YMD <= TB_CAR_FFNLG_TRGT.검사종료일자
&& record.CHANGE_JOB_SE_CODE == "11") { // 11 = 명의이전 코드
return true;
}
}
결과 처리
- 비고 컬럼:
"[상품용] 갑부정보"
2. 이첩 검증 (이첩-1, 이첩-2 병합 로직)
필요 API: 자동차기본정보
부과기준일 결정
int dayCnt = TB_CAR_FFNLG_TRGT.DAYCNT; // textFile 일수
if (dayCnt > 115) {
// 이첩-2
부과기준일 = TB_CAR_FFNLG_TRGT.검사종료일자.plusDays(115);
} else {
// 이첩-1
부과기준일 = TB_CAR_FFNLG_TRGT.검사일자;
}
API 호출
// 부과기준일 기준으로 자동차기본정보 API 호출
BasicResponse response = 자동차기본정보API.call(부과기준일, 차량번호);
법정동코드 비교 로직 (공통)
/**
* 이첩 조건: 법정동코드 불일치 검증
* 사용본거지법정동코드 앞 4자리 != 사용자 조직코드 앞 4자리
*/
private boolean checkTransferCondition_LegalDongMismatch(
BasicResponse.Record basicInfo,
String userId,
String vhclno
) {
String useStrnghldLegaldongCode = basicInfo.getUseStrnghldLegaldongCode();
// 1. 법정동코드 유효성 검사
if (useStrnghldLegaldongCode == null || useStrnghldLegaldongCode.length() < 4) {
log.debug("[이첩] 법정동코드 없음. 차량번호: {}", vhclno);
return false;
}
// 2. 사용자 정보 조회
SystemUserVO userInfo = userMapper.selectUser(userId);
if (userInfo == null || userInfo.getOrgCd() == null) {
log.debug("[이첩] 사용자 정보 없음. 사용자ID: {}", userId);
return false;
}
// 3. 법정동코드 앞 4자리 vs 사용자 조직코드 앞 4자리 비교
String legalDong4 = useStrnghldLegaldongCode.substring(0, 4);
String userOrgCd = userInfo.getOrgCd();
String userOrg4 = userOrgCd.length() >= 4
? userOrgCd.substring(0, 4)
: userOrgCd;
// 4. 일치 여부 판단
if (legalDong4.equals(userOrg4)) {
log.debug("[이첩] 법정동코드 일치. 차량번호: {}, 법정동: {}, 조직: {}",
vhclno, legalDong4, userOrg4);
return false; // 일치하면 이첩 대상 아님
}
log.info("[이첩] 법정동코드 불일치! 차량번호: {}, 법정동: {}, 조직: {}",
vhclno, legalDong4, userOrg4);
return true; // 불일치하면 이첩 대상
}
결과 처리
| 구분 | 조건 | 비고 컬럼 형식 |
|---|---|---|
| 이첩-1 | DAYCNT <= 115 |
"서울시 용산구/ 이경호, 검사일사용본거지, [검사대상, 사용자 조직코드 앞 4자리 및 법정동명]" |
| 이첩-2 | DAYCNT > 115 |
"전라남도 순천시 / 김정대, 115일 도래지, [2개의 api 법정동코드 및 법정동명]" |
데이터 모델
TB_CAR_FFNLG_TRGT (과태료 대상 테이블)
| 컬럼명 | 설명 | 용도 |
|---|---|---|
| 검사일 | 검사 기준일 | API 호출 파라미터 |
| 검사종료일자 | 검사 종료 일자 | 115일 계산 기준 |
| 유효기간만료일 | 유효기간 만료일 | 상품용 갑부 비교 시작일 |
| DAYCNT | textFile 일수 | 이첩-1/2 분기 조건 |
| 비고 | 검증 결과 메시지 | 결과 저장 |
코드 정의
| 코드 | 코드값 | 설명 |
|---|---|---|
| CHANGE_JOB_SE_CODE | 11 | 명의이전 |
처리 흐름도
시작
│
▼
[차량번호 조회]
│
▼
[1. 상품용 검증] ──(조건 충족)──> [비고 기록] ──> [다음 차량]
│
│ (조건 미충족)
▼
[2. DAYCNT 확인]
│
├─ (> 115) ──> [이첩-2: 부과기준일 = 검사종료일자 + 115일]
│
└─ (<= 115) ──> [이첩-1: 부과기준일 = 검사일]
│
▼
[법정동코드 비교] (공통)
│
├─ (불일치) ──> [비고 기록] ──> [다음 차량]
│
└─ (일치) ──> [다음 차량]
구현 시 주의사항
- API 호출 순서 준수: 각 검증 단계별로 필요한 API만 호출
- 조건 우선순위: 상품용 > 이첩 순서로 검증
- 조기 종료: 조건 충족 시 즉시 다음 차량으로 이동
- 비고 컬럼: 각 조건별 정해진 형식으로 기록
- 법정동코드 길이 검증: 최소 4자리 이상 필요
내가 text 로 정리한 내용
-- 1. 상품용 [자동차등록원부(갑) 필요] ----- 필요한 api 정보
- 자동차기본정보 api 호출 [차량번호, 부과일자:검사일] -> response.차대번호, response.소유자명
- 자동차기본정보 api 호출 [1.response.차대번호, 부과일자:오늘일자] -> response.차량번호, response.성명, response.민원인주민번호, response.민원인법정동코드
- 자동차등록원본(갑) api 호출 [2.response.차량번호, 2.response.성명, 2.response.민원인주민번호, 2.response.민원인법정동코드] -- 비교로직에 사용될 api response 정보
- TB_CAR_FFNLG_TRGT.검사일 기준 api 호출
- tb_car_ffnlg_trgt.OWNR_NM like ‘%상품용%’
- (갑부 상세(LedgerRecord) List.CHG_YMD between TB_CAR_FFNLG_TRGT.유효기간만료일 and TB_CAR_FFNLG_TRGT.검사종료일자) and (갑부 상세 List.CHANGE_JOB_SE_CODE = '11' --명의이전 코드)
- TB_CAR_FFNLG_TRGT 비고 : 조건에 걸린 - "[상품용] 갑부정보"
-- 2. 이첩1, 2 병합로직 -- 부과기준일 구하는 부분만 다르고 나머지 법정도코드 비교로직은 동일, 대신 TB_CAR_FFNLG_TRGT 비고 컬럼에 각기 알맞는 value 값 넣어줘야함. if(TB_CAR_FFNLG_TRGT.DAYCNT(textFile 일수) > 115){ 부과기준일 = (TB_CAR_FFNLG_TRGT.검사종료일자 + 115일) TB_CAR_FFNLG_TRGT 비고 : 조건에 걸린 - "전라남도 순천시 / 김정대, 115일 도래지, [2개의 api 법정동코드 및 법정동명]" 이첩-2 }else{ 부과기준일 = (TB_CAR_FFNLG_TRGT.검사일자) table 비고 : 조건에 걸린 - "서울시 용산구/ 이경호, 검사일사용본거지, [검사대상, 사용자 조직코드 앞 4자리 및 법정동명]" 이첩-1 } 아래는 이첩1,2 모두 공용 자동차기본정보 (부과기준일, 차량번호)api call, // 법정동코드 유효성 검사 if (useStrnghldLegaldongCode == null || useStrnghldLegaldongCode.length() < 4) { log.debug("[이첩][조건1] 법정동코드 없음. 차량번호: {}", vhclno); return false; }
// 사용자 정보 조회 SystemUserVO userInfo = userMapper.selectUser(userId); if (userInfo == null || userInfo.getOrgCd() == null) { log.debug("[이첩][조건1] 사용자 정보 없음. 사용자ID: {}", userId); return false; }
// 법정동코드 앞 4자리 vs 사용자 조직코드 앞 4자리 비교 String legalDong4 = useStrnghldLegaldongCode.substring(0, 4); String userOrgCd = userInfo.getOrgCd(); String userOrg4 = userOrgCd.length() >= 4 ? userOrgCd.substring(0, 4) : userOrgCd;
if (legalDong4.equals(userOrg4)) { log.debug("[이첩][조건1] 법정동코드 일치. 차량번호: {}, 법정동: {}, 조직: {}", vhclno, legalDong4, userOrg4); return false; }
log.info("[이첩][조건1] 법정동코드 불일치! 차량번호: {}, 법정동: {}, 조직: {}", vhclno, legalDong4, userOrg4); return true;