You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
VIPS/docs/자동차과태료_비교로직_정리-[지연].md

20 KiB

자동차 과태료 비교 로직 명세서 (지연)

개요

자동차 과태료 부과 대상(지연)을 검증하기 위한 비교 로직 정의서입니다.

구현 위치

  • Checker 클래스: src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/delay_checker/
    • ProductUseChecker.java - 1. 상품용(명의이전)
    • ProductUseChnageChecker.java - 1-1. 상품용(변경등록)
    • ProductCloseWithin31Checker.java - 2. 내사종결(명의이전 이전소유자 상품용, 31일 이내)
    • OwnerCloseWithin31Checker.java - 3. 내사종결(순수 명의이전, 31일 이내)
    • ProductLevyOver31Checker.java - 4. 날짜수정후부과(명의이전 이전소유자 상품용, 31일 초과)
    • OwnerLevyOver31Checker.java - 5. 날짜수정후부과(순수 명의이전, 31일 초과)
    • TransferCase115DayChecker.java - 6. 이첩

기본 설정

  • 비교로직에 사용되는 API: ExternalVehicleApiServiceImpl.getBasicInfo, getLedgerInfo 호출
  • 날짜 유틸리티: DateUtil.parseDate(), DateUtil.formatDateString() 사용
  • 일수 계산 기준: DAYS_THRESHOLD = 31일

문서 이력

일자 변경 내용 비고
2025-12-08 delay_checker 소스 기준 전면 재작성 실제 코드와 일치하도록 정리
2025-12-03 실제 소스 코드 기준으로 전면 재작성 Javadoc과 실제 로직 차이 명시
2025-12-02 내사종결 로직 추가 및 상품용 조건 변경 명의이전 31일 이내 조건 추가

처리 규칙

중요: 순서가 중요함!

  1. 상품용(명의이전) → 1-1. 상품용(변경등록) → 2. 내사종결(상품용) → 3. 내사종결(명의이전) → 4. 날짜수정(상품용) → 5. 날짜수정(명의이전) → 6. 이첩
  • 조건에 걸리는 순간 다음 차량번호 비교로 진행
  • 각 비교 로직별로 개별 API 호출 수행

비교 로직 상세

1. 상품용 검증 (ProductUseChecker)

처리상태코드: 02 (상품용) 클래스: ProductUseChecker.java

API 호출 순서

순서 API 입력 파라미터 출력 데이터 용도
1 자동차기본정보 차량번호, 부과일자=검사일 차대번호(vin), 소유자명, 대표소유자회원번호 검사일 기준 소유자 확인
2 자동차기본정보 1.차대번호, 부과일자=오늘 차량번호, 성명, 주민번호, 법정동코드 현재 소유자 정보
3 자동차등록원부(갑) 2.차량번호, 2.성명, 2.주민번호, 2.법정동코드 갑부 상세 List 명의이전 이력 조회
4 자동차기본정보 1.차대번호, 부과일자=CHG_YMD 소유자명, 대표소유자회원번호 명의이전 시점 소유자 확인

비교 조건

1. Step1 소유자명.contains("상품용") ← 상품용 아니면 return null

2. 갑부에서 명의이전(11) 레코드 찾기
   - CHG_TASK_SE_CD == "11"
   - CHG_YMD <= 검사종료일자
   - 가장 마지막 일자 선택
   ← 없으면 return null

3. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
   ← 불일치면 return null

→ 모든 조건 충족: 상품용(02) 처리

DB 업데이트 필드

existingData.setTaskPrcsSttsCd("02");  // 상품용
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd("11");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());

1-1. 상품용-변경등록 검증 (ProductUseChnageChecker)

처리상태코드: 02 (상품용) 클래스: ProductUseChnageChecker.java

API 호출 순서

순서 API 입력 파라미터 출력 데이터 용도
1 자동차기본정보 차량번호, 부과일자=검사일 차대번호(vin), 소유자명, 대표소유자회원번호 검사일 기준 소유자 확인
2 자동차기본정보 1.차대번호, 부과일자=오늘 차량번호, 성명, 주민번호, 법정동코드 현재 소유자 정보
3 자동차등록원부(갑) 2.차량번호, 2.성명, 2.주민번호, 2.법정동코드 갑부 상세 List 변경등록 이력 조회
4 자동차기본정보 1.차대번호, 부과일자=CHG_YMD 소유자명, 대표소유자회원번호 변경등록 시점 소유자 확인

비교 조건

1. Step1 소유자명.contains("상품용") ← 상품용 아니면 return null

2. 갑부에서 변경등록(21) 레코드 찾기
   - CHG_TASK_SE_CD == "21"
   - CHG_YMD <= 검사종료일자
   - spcablMttr.contains("성명") ← 성명 변경 포함 필수
   - 가장 마지막 일자 선택
   ← 없으면 return null

3. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
   ← 불일치면 return null

→ 모든 조건 충족: 상품용(02) 처리

DB 업데이트 필드

existingData.setTaskPrcsSttsCd("02");  // 상품용
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd("21");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());

2. 내사종결 - 명의이전 이전소유자 상품용, 31일 이내 (ProductCloseWithin31Checker)

처리상태코드: 04 (내사종결) 클래스: ProductCloseWithin31Checker.java

API 호출 순서

순서 API 입력 파라미터 출력 데이터 용도
1 자동차기본정보 차량번호, 부과일자=검사일 차대번호, 소유자명 검사일 기준 소유자 확인
2 자동차기본정보 1.차대번호, 부과일자=오늘 차량번호, 성명, 주민번호, 법정동코드 현재 소유자 정보
3 자동차등록원부(갑) 2.차량번호, 2.성명, 2.주민번호, 2.법정동코드 갑부 상세 List 명의이전 이력 조회
4 자동차기본정보 1.차대번호, 부과일자=CHG_YMD-1일 소유자명 명의이전 직전 소유자 확인

비교 조건

1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
   !Step1 소유자명.contains("상품용") → 계속 진행

2. 갑부에서 명의이전(11) 레코드 찾기
   - CHG_TASK_SE_CD == "11"
   - CHG_YMD <= 검사일
   - 가장 마지막 일자 선택
   ← 없으면 return null

3. 일수 계산: 명의이전일자 ~ 검사일
   - 0~31일 이내 → 계속 진행
   - 31일 초과 → return null (4번에서 처리)

4. Step4 소유자명.contains("상품용")
   ← 상품용 아니면 return null

→ 모든 조건 충족: 내사종결(04) 처리

DB 업데이트 필드

existingData.setTaskPrcsSttsCd("04");  // 내사종결
existingData.setCarBscMttrInqFlnm(step4OwnerName);  // 명의이전 직전 소유자명
existingData.setCarRegFrmbkChgTaskSeCd("11");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());

3. 내사종결 - 순수 명의이전, 31일 이내 (OwnerCloseWithin31Checker)

처리상태코드: 04 (내사종결) 클래스: OwnerCloseWithin31Checker.java

API 호출 순서

순서 API 입력 파라미터 출력 데이터 용도
1 자동차기본정보 차량번호, 부과일자=검사일 차대번호, 소유자명, 대표소유자회원번호 검사일 기준 소유자 확인
2 자동차기본정보 1.차대번호, 부과일자=오늘 차량번호, 성명, 주민번호, 법정동코드 현재 소유자 정보
3 자동차등록원부(갑) 2.차량번호, 2.성명, 2.주민번호, 2.법정동코드 갑부 상세 List 명의이전 이력 조회
4 자동차기본정보 1.차대번호, 부과일자=CHG_YMD 소유자명, 대표소유자회원번호 명의이전 시점 소유자 확인

비교 조건

1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
   !Step1 소유자명.contains("상품용") → 계속 진행

2. 갑부에서 명의이전(11) 레코드 찾기
   - CHG_TASK_SE_CD == "11"
   - 유효기간만료일-90일 <= CHG_YMD <= 검사종료일자
   - 가장 마지막 일자 선택
   ← 없으면 return null

3. 일수 계산: 명의이전일자 ~ 검사일
   - 0~31일 이내 → 계속 진행
   - 31일 초과 → return null (5번에서 처리)

4. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
   ← 불일치면 return null

→ 모든 조건 충족: 내사종결(04) 처리

DB 업데이트 필드

existingData.setTaskPrcsSttsCd("04");  // 내사종결
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd("11");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());

4. 날짜수정후부과 - 명의이전 이전소유자 상품용, 31일 초과 (ProductLevyOver31Checker)

처리상태코드: 05 (날짜 수정 후 부과) 클래스: ProductLevyOver31Checker.java

API 호출 순서

순서 API 입력 파라미터 출력 데이터 용도
1 자동차기본정보 차량번호, 부과일자=검사일 차대번호, 소유자명 검사일 기준 소유자 확인
2 자동차기본정보 1.차대번호, 부과일자=오늘 차량번호, 성명, 주민번호, 법정동코드 현재 소유자 정보
3 자동차등록원부(갑) 2.차량번호, 2.성명, 2.주민번호, 2.법정동코드 갑부 상세 List 명의이전 이력 조회
4 자동차기본정보 1.차대번호, 부과일자=CHG_YMD-1일 소유자명 명의이전 직전 소유자 확인

비교 조건

1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
   !Step1 소유자명.contains("상품용") → 계속 진행

2. 갑부에서 명의이전(11) 레코드 찾기
   - CHG_TASK_SE_CD == "11"
   - CHG_YMD <= 검사일
   - 가장 마지막 일자 선택
   ← 없으면 return null

3. 일수 계산: 명의이전일자 ~ 검사일
   - 31일 초과 → 계속 진행
   - 0~31일 이내 → return null (2번에서 처리)

4. Step4 소유자명.contains("상품용")
   ← 상품용 아니면 return null

→ 모든 조건 충족: 날짜수정후부과(05) 처리

DB 업데이트 필드

existingData.setTaskPrcsSttsCd("05");  // 날짜수정후부과
existingData.setCarBscMttrInqFlnm(step4OwnerName);  // 명의이전 직전 소유자명
existingData.setCarRegFrmbkChgTaskSeCd("11");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());

5. 날짜수정후부과 - 순수 명의이전, 31일 초과 (OwnerLevyOver31Checker)

처리상태코드: 05 (날짜 수정 후 부과) 클래스: OwnerLevyOver31Checker.java

API 호출 순서

순서 API 입력 파라미터 출력 데이터 용도
1 자동차기본정보 차량번호, 부과일자=검사일 차대번호, 소유자명, 대표소유자회원번호 검사일 기준 소유자 확인
2 자동차기본정보 1.차대번호, 부과일자=오늘 차량번호, 성명, 주민번호, 법정동코드 현재 소유자 정보
3 자동차등록원부(갑) 2.차량번호, 2.성명, 2.주민번호, 2.법정동코드 갑부 상세 List 명의이전 이력 조회
4 자동차기본정보 1.차대번호, 부과일자=CHG_YMD 소유자명, 대표소유자회원번호 명의이전 시점 소유자 확인

비교 조건

1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
   !Step1 소유자명.contains("상품용") → 계속 진행

2. 갑부에서 명의이전(11) 레코드 찾기
   - CHG_TASK_SE_CD == "11"
   - 유효기간만료일-90일 <= CHG_YMD <= 검사종료일자
   - 가장 마지막 일자 선택
   ← 없으면 return null

3. 일수 계산: 명의이전일자 ~ 검사일
   - 31일 초과 → 계속 진행
   - 0~31일 이내 → return null (3번에서 처리)

4. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
   ← 불일치면 return null

→ 모든 조건 충족: 날짜수정후부과(05) 처리

DB 업데이트 필드

existingData.setTaskPrcsSttsCd("05");  // 날짜수정후부과
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd("11");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());

6. 이첩 검증 (TransferCase115DayChecker)

처리상태코드: 03 (이첩) 클래스: TransferCase115DayChecker.java

API 호출

API 입력 파라미터 출력 데이터 용도
자동차기본정보 차량번호, 부과일자=부과기준일 사용본거지법정동코드 부과기준일 기준 사용본거지 확인

비교 조건

1. DAYCNT 값으로 부과기준일 계산
   - DAYCNT > 115: 이첩-2 (부과기준일 = 검사종료일자 + 115일)
   - DAYCNT <= 115: 이첩-1 (부과기준일 = 검사일자)
   ← DAYCNT 없으면 return null

2. 자동차기본정보(차량번호, 부과기준일) 호출
   → 사용본거지법정동코드 조회

3. 법정동코드 앞 4자리 != 사용자 조직코드 앞 4자리
   ← 일치하면 return null

→ 불일치: 이첩(03) 처리

결과 처리

구분 조건 비고 컬럼 형식
이첩-1 DAYCNT <= 115 "{시군구명}, 검사일사용본거지, [사용자 조직코드 앞 4자리: {userOrg4}, 법정동명: {sggNm}]"
이첩-2 DAYCNT > 115 "{시군구명}, 115일 도래지, [법정동코드: {legalDong4}, 법정동명: {sggNm}]"

DB 업데이트 필드

existingData.setTaskPrcsSttsCd("03");  // 이첩
existingData.setCarBscMttrInqFlnm(existingData.getOwnrNm());  // 기존 소유자명 유지
existingData.setCarBscMttrInqSggCd(sggCd);
existingData.setCarBscMttrInqSggNm(sggNm);

처리 흐름도

시작
  │
  ▼
[차량번호 조회]
  │
  ▼
┌──────────────────────────────────────────────┐
│ 1. 상품용-명의이전 (ProductUseChecker)       │
│    조건: 검사일 소유자명.contains("상품용")   │
│         + 명의이전(11) 레코드 존재            │
│    → 조건 충족: 상품용(02)                   │
└──────────────────────────────────────────────┘
  │ (조건 미충족)
  ▼
┌──────────────────────────────────────────────┐
│ 1-1. 상품용-변경등록 (ProductUseChnageChecker)│
│    조건: 검사일 소유자명.contains("상품용")   │
│         + 변경등록(21) + 성명변경 포함        │
│    → 조건 충족: 상품용(02)                   │
└──────────────────────────────────────────────┘
  │ (조건 미충족)
  ▼
┌──────────────────────────────────────────────┐
│ 2. 내사종결-상품용 (ProductCloseWithin31Checker) │
│    조건: 31일 이내 + 명의이전 전 상품용       │
│    → 조건 충족: 내사종결(04)                 │
└──────────────────────────────────────────────┘
  │ (조건 미충족)
  ▼
┌──────────────────────────────────────────────┐
│ 3. 내사종결-명의이전 (OwnerCloseWithin31Checker) │
│    조건: 31일 이내 + 동일 소유자              │
│    → 조건 충족: 내사종결(04)                 │
└──────────────────────────────────────────────┘
  │ (조건 미충족)
  ▼
┌──────────────────────────────────────────────┐
│ 4. 날짜수정-상품용 (ProductLevyOver31Checker) │
│    조건: 31일 초과 + 명의이전 전 상품용       │
│    → 조건 충족: 날짜수정후부과(05)           │
└──────────────────────────────────────────────┘
  │ (조건 미충족)
  ▼
┌──────────────────────────────────────────────┐
│ 5. 날짜수정-명의이전 (OwnerLevyOver31Checker) │
│    조건: 31일 초과 + 동일 소유자              │
│    → 조건 충족: 날짜수정후부과(05)           │
└──────────────────────────────────────────────┘
  │ (조건 미충족)
  ▼
┌──────────────────────────────────────────────┐
│ 6. 이첩 (TransferCase115DayChecker)          │
│    조건: 법정동코드 앞4자리 != 조직코드 앞4자리│
│    → 조건 충족: 이첩(03)                     │
└──────────────────────────────────────────────┘
  │ (조건 미충족)
  ▼
[다음 차량]

요약 정리

처리상태코드 매핑

코드 상태명 처리 로직 클래스
02 상품용 검사일 소유자가 상품용 + 명의이전(11) ProductUseChecker
02 상품용 검사일 소유자가 상품용 + 변경등록(21) + 성명변경 ProductUseChnageChecker
04 내사종결 명의이전 전 상품용 (31일 이내) ProductCloseWithin31Checker
04 내사종결 순수 명의이전 (31일 이내) OwnerCloseWithin31Checker
05 날짜수정후부과 명의이전 전 상품용 (31일 초과) ProductLevyOver31Checker
05 날짜수정후부과 순수 명의이전 (31일 초과) OwnerLevyOver31Checker
03 이첩 법정동코드 불일치 TransferCase115DayChecker

상품용 vs 순수 명의이전 비교

구분 상품용 케이스 (2, 4번) 순수 명의이전 케이스 (3, 5번)
검사일 소유자 상품용 아님 상품용 아님
명의이전 직전 소유자 상품용 포함 소유자 회원번호 일치
Step 4 확인사항 소유자명.contains("상품용") 대표소유자회원번호 == Step1
갑부 검색 조건 CHG_YMD <= 검사일 유효기간만료일-90일 <= CHG_YMD <= 검사종료일자
일수 기준 31일 이내/초과 31일 이내/초과
처리상태코드 31일 이내: 04, 초과: 05 31일 이내: 04, 초과: 05

참고 상수 및 유틸리티

상수

// 일수 기준값
private static final int DAYS_THRESHOLD = 31;

// 처리상태코드
TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_02_PRODUCT_USE = "02"
TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_03_TRANSFER = "03"
TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_04_INVESTIGATION_CLOSED = "04"
TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_05_DATE_MODIFIED_LEVY = "05"

// 변경업무구분코드
"11" = 명의이전
"21" = 변경등록

문서 작성 완료일: 2025-12-08 실제 소스 코드 기준: delay_checker 폴더 내 Checker 클래스들 분석 대상 클래스: 7개 (ProductUseChecker, ProductUseChnageChecker, ProductCloseWithin31Checker, OwnerCloseWithin31Checker, ProductLevyOver31Checker, OwnerLevyOver31Checker, TransferCase115DayChecker)