### feat: `Step 0` 및 `Step 1` 공통 로직 도입과 검사 체커 로직 개선

- **공통 로직 추가**
  - **`Step 0`, `Step 1`**: `ComparisonOmServiceImpl` 및 `ComparisonServiceImpl`에 공통 API 호출 로직 추가.
    - `step0Response`(차량번호), `step1Response`(차대번호) 생성 및 유효성 검증 로직 추가.
    - 모든 Checker에서 해당 공통 데이터를 활용 가능하도록 수정.

- **체커 순서 변경 및 메서드 개선**
  - [**미필**] 이첩 순서 변경: 기존 3번 → 2번으로 조정, 명의이전 확인 순서 조정.
  - [**지연**] 이첩 순서 변경: 기존 6번 → 4번으로 조정.
  - 기존 Checker 메서드에 공통화된 **`step0Response`, `step1Response`** 전달하도록 메서드 시그니처 업데이트.
  - 중복된 API 호출 제거 및 공통 데이터 활용으로 효율성 증가.

- **불필요 로직 제거 및 코드 정리**
  - 각 체커별 중복된 `Step 0`, `Step 1` API 호출 삭제.
  - 공통 응답 데이터 재활용.
  - 주석 보완 및 처리 흐름 가독성 강화.

- **DB 업데이트 관련 로직 명확화**
  - `이첩` 관련 처리 코드(시군구명, 법정동명) 구현 방식 및 String 결과 형식 문서화.

- **기타**
  - 문서 수정: `docs/자동차과태료_비교로직_정리-[미필/지연].md` 최종 수정일 업데이트.
  - 체커 순서 변경에 따른 처리 로직 및 데이터 흐름도 재정리.
onlyExternalApi
박성영 22 hours ago
parent ca004dce5b
commit 293933e0ba

@ -5,10 +5,11 @@
자동차 과태료 부과 대상(미필)을 검증하기 위한 비교 로직 정의서입니다.
### 구현 위치
- **Main Service**: `src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/ComparisonOmServiceImpl.java`
- **Checker 클래스**: `src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/`
- `ProductUseOmChecker.java` - 1. 상품용 : 상품용
- `OwnerTransferOmChecker.java` - 2. 명의이전 소유자 확인 : 명의이전(25.9.5.) 이전소유자 상품용, 경상남도 창원시/ 현대캐피탈 주식회사, 미수검명의이전(25.5.19.)(37하1553)
- `TransferOmChecker.java` - 3. 이첩 : 경기도 과천시/ 이정호, 115일 도래지
- `TransferOmChecker.java` - 2. 이첩 : 경기도 과천시/ 이정호, 115일 도래지
- `OwnerTransferOmChecker.java` - 3. 명의이전 소유자 확인 : 명의이전(25.9.5.) 이전소유자 상품용, 경상남도 창원시/ 현대캐피탈 주식회사, 미수검명의이전(25.5.19.)(37하1553)
### 기본 설정
- 비교로직에 사용되는 API: `ExternalVehicleApiServiceImpl.getBasicInfo`, `getLedgerInfo` 호출
@ -19,15 +20,58 @@
| 일자 | 변경 내용 | 비고 |
|------|----------|------|
| 2025-12-08 | om_checker 소스 기준 전면 작성 | 실제 코드와 일치하도록 정리 |
| 2025-12-15 | Step 0, Step 1 공통 로직 추가 및 순서 변경 | 이첩 순서 변경 (3번→2번) |
| 2025-12-09 | 검사유효기간 종료일 + 31일 로직 반영 | ProductUseOmChecker, OwnerTransferOmChecker |
| 2025-12-08 | om_checker 소스 기준 전면 작성 | 실제 코드와 일치하도록 정리 |
### 처리 규칙
> **중요**: 순서가 중요함!
> 1. 상품용 → 2. 명의이전 소유자 확인 → 3. 이첩
>
> **공통 로직 (한 번만 실행)**:
> - Step 0: 자동차기본정보 조회 (차량번호 + 오늘일자)
> - Step 1: 자동차기본정보 조회 (차대번호 + 부과일자)
>
> **Checker 순서**:
> 1. 상품용 → 2. 이첩 → 3. 명의이전 소유자 확인
> - 조건에 걸리는 순간 다음 차량번호 비교로 진행
> - 각 비교 로직별로 개별 API 호출 수행
> - 각 Checker는 공통 API 응답(step0Response, step1Response)을 파라미터로 받음
---
## 공통 로직 (ComparisonOmServiceImpl)
### Step 0: 자동차기본정보 조회 (현재 차량 정보)
**API 호출**: `getBasicInfo`
| 입력 | 값 |
|------|-----|
| 차량번호 | `vhclno` |
| 부과일자 | 오늘 날짜 (`LocalDate.now()`) |
**출력**:
- `step0Response` → 모든 Checker에 전달
- 주요 필드: `vin` (차대번호)
**실패 시**: 비교 로직 종료 (return null)
---
### Step 1: 자동차기본정보 조회 (부과일자 기준 정보)
**API 호출**: `getBasicInfo`
| 입력 | 값 |
|------|-----|
| 차대번호 | `step0Response.vin` |
| 부과일자 | 검사유효기간 종료일 + 146일 (`levyCrtrYmd`) |
**출력**:
- `step1Response` → 모든 Checker에 전달
- 주요 필드: `소유자명`, `대표소유자회원번호`
**실패 시**: 비교 로직 종료 (return null)
---
@ -38,21 +82,22 @@
**처리상태코드**: `02` (상품용)
**클래스**: `ProductUseOmChecker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사유효기간종료일+146일` | `차대번호(vin)`, `소유자명`, `대표소유자회원번호` | 부과일자 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
**참고**: Step 0, Step 1은 공통 로직에서 이미 호출됨
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") ← 상품용 아니면 return null
1. step1Response 소유자명.contains("상품용") ← 상품용 아니면 return null
2. Step2 대표소유자회원번호 == Step1 대표소유자회원번호
2. step1Response 대표소유자회원번호 == step0Response 대표소유자회원번호
← 불일치면 return null
3. 갑부에서 명의이전(11) 레코드 찾기
@ -61,7 +106,7 @@
- 가장 마지막 일자 선택
← 없으면 return null
4. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
4. Step4 대표소유자회원번호 == step1Response 대표소유자회원번호
← 불일치면 return null
→ 모든 조건 충족: 상품용(02) 처리
@ -78,101 +123,103 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
---
### 2. 명의이전 소유자 확인 (`OwnerTransferOmChecker`)
### 2. 이첩 검증 (`TransferOmChecker`)
**처리상태코드**: `01` (그대로 접수)
**클래스**: `OwnerTransferOmChecker.java`
**처리상태코드**: `03` (이첩)
**클래스**: `TransferOmChecker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사유효기간종료일+146일` | `차대번호(vin)`, `소유자명` | 부과일자 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD-1일` | `소유자명` | 명의이전 직전 소유자 확인 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=검사유효기간종료일-90일` | `소유자명`, `소유자회원번호` | 90일 전 소유자 확인 |
| 3 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `소유자명`, `소유자회원번호` | 현재 소유자 확인 |
**참고**: Step 0, Step 1은 공통 로직에서 이미 호출됨
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
!Step1 소유자명.contains("상품용") → 계속 진행
1. step1Response 소유자명.contains("상품용") → return null (1번에서 처리됨)
!step1Response 소유자명.contains("상품용") → 계속 진행
2. 갑부에서 명의이전(11) 레코드 찾기
- CHG_TASK_SE_CD == "11"
- CHG_YMD > 검사유효기간 종료일 + 31일
- 가장 마지막 일자 선택
← 없으면 return null
2. step1Response 소유자회원번호 != Step2 소유자회원번호
← 일치하면 return null
3. Step4 소유자명 확인
- "상품용" 포함 → 접수(01)
- "상품용" 미포함 → 접수(01)
3. step1Response 소유자회원번호 != Step3 소유자회원번호
← 일치하면 return null
→ 모든 조건 충족: 접수(01) 처리
4. 법정동코드 앞 4자리 == 사용자 조직코드 앞 4자리
← 일치하면 return null
→ 불일치: 이첩(03) 처리
```
#### 결과 분기
#### 결과 처리
| Step4 소유자명 | 처리상태코드 | 비고 형식 |
|---------------|-----------|-----------|
| 상품용 포함 | `01` (접수) | 명의이전(날짜) 이전소유자 상품용 |
| 상품용 미포함 | `01` (접수) | 명의이전(날짜) |
| 구분 | 비고 컬럼 형식 |
|------|---------------|
| 이첩 | `"{시군구명}, 115일 도래지, [법정동코드: {legalDong4}, 법정동명: {sggNm}]"` |
#### DB 업데이트 필드
```java
existingData.setTaskPrcsSttsCd("01"); // 접수
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd("11");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
existingData.setTaskPrcsSttsCd("03"); // 이첩
existingData.setCarBscMttrInqFlnm(step1RprsOwnrNm);
existingData.setCarBscMttrInqSggCd(sggCd);
existingData.setCarBscMttrInqSggNm(sggNm);
```
---
### 3. 이첩 검증 (`TransferOmChecker`)
### 3. 명의이전 소유자 확인 (`OwnerTransferOmChecker`)
**처리상태코드**: `03` (이첩)
**클래스**: `TransferOmChecker.java`
**처리상태코드**: `01` (그대로 접수)
**클래스**: `OwnerTransferOmChecker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사유효기간종료일+146일` | `소유자명`, `소유자회원번호`, `사용본거지법정동코드`, `차대번호` | 부과일자 기준 정보 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=검사유효기간종료일-90일` | `소유자명`, `소유자회원번호` | 90일 전 소유자 확인 |
| 3 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `소유자명`, `소유자회원번호` | 현재 소유자 확인 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD-1일` | `소유자명` | 명의이전 직전 소유자 확인 |
**참고**: Step 0, Step 1은 공통 로직에서 이미 호출됨
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
!Step1 소유자명.contains("상품용") → 계속 진행
2. Step1 소유자회원번호 != Step2 소유자회원번호
← 불일치면 return null
1. step1Response 소유자명.contains("상품용") → return null (1번에서 처리됨)
!step1Response 소유자명.contains("상품용") → 계속 진행
3. Step1 소유자회원번호 != Step3 소유자회원번호
← 불일치면 return null
2. 갑부에서 명의이전(11) 레코드 찾기
- CHG_TASK_SE_CD == "11"
- CHG_YMD > 검사유효기간 종료일 + 31일
- 가장 마지막 일자 선택
← 없으면 return null
4. 법정동코드 앞 4자리 == 사용자 조직코드 앞 4자리
← 일치하면 return null
3. Step4 소유자명 확인
- "상품용" 포함 → 접수(01)
- "상품용" 미포함 → 접수(01)
불일치: 이첩(03) 처리
모든 조건 충족: 접수(01) 처리
```
#### 결과 처리
#### 결과 분기
| 구분 | 비고 컬럼 형식 |
|------|---------------|
| 이첩 | `"{시군구명}, 115일 도래지, [법정동코드: {legalDong4}, 법정동명: {sggNm}]"` |
| Step4 소유자명 | 처리상태코드 | 비고 형식 |
|---------------|-----------|-----------|
| 상품용 포함 | `01` (접수) | 명의이전(날짜) 이전소유자 상품용 |
| 상품용 미포함 | `01` (접수) | 명의이전(날짜) |
#### DB 업데이트 필드
```java
existingData.setTaskPrcsSttsCd("03"); // 이첩
existingData.setCarBscMttrInqFlnm(step1RprsOwnrNm);
existingData.setCarBscMttrInqSggCd(sggCd);
existingData.setCarBscMttrInqSggNm(sggNm);
existingData.setTaskPrcsSttsCd("01"); // 접수
existingData.setCarBscMttrInqFlnm(step4OwnerName);
existingData.setCarRegFrmbkChgTaskSeCd("11");
existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
```
---
@ -187,8 +234,21 @@ existingData.setCarBscMttrInqSggNm(sggNm);
┌──────────────────────────────────────────────┐
│ 공통: Step 0 - 자동차기본정보 (차량번호, 오늘) │
│ → step0Response (차대번호) │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ 공통: Step 1 - 자동차기본정보 (차대번호, 부과일자)│
│ → step1Response (소유자명) │
│ 부과일자 = 검사유효기간종료일 + 146일 │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ 1. 상품용 (ProductUseOmChecker) │
│ 조건: 부과일자 소유자명.contains("상품용") │
│ 조건: step1 소유자명.contains("상품용")
│ + 명의이전(11) 레코드 존재 │
│ + CHG_YMD <= 검사유효기간종료일+31일 │
│ + 소유자회원번호 일치 │
@ -197,21 +257,21 @@ existingData.setCarBscMttrInqSggNm(sggNm);
│ (조건 미충족)
┌──────────────────────────────────────────────┐
│ 2. 명의이전 소유자 확인 (OwnerTransferOmChecker)│
│ 조건: 부과일자 소유자명에 상품용 미포함 │
│ + CHG_YMD > 검사유효기간종료일+31일 │
│ + 명의이전(11) 레코드 존재 │
│ → 조건 충족: 접수(01) │
│ 2. 이첩 (TransferOmChecker) │
│ 조건: 소유자명에 상품용 미포함 │
│ + step1/step2 소유자 다름 │
│ + step1/step3 소유자 다름 │
│ + 법정동코드 앞4자리 != 조직코드 앞4자리│
│ → 조건 충족: 이첩(03) │
└──────────────────────────────────────────────┘
│ (조건 미충족)
┌──────────────────────────────────────────────┐
│ 3. 이첩 (TransferOmChecker) │
│ 조건: 소유자명에 상품용 미포함 │
│ + 1단계/2단계 소유자 같음 │
│ + 1단계/3단계 소유자 같음 │
│ + 법정동코드 앞4자리 != 조직코드 앞4자리│
│ → 조건 충족: 이첩(03) │
│ 3. 명의이전 소유자 확인 (OwnerTransferOmChecker)│
│ 조건: step1 소유자명에 상품용 미포함 │
│ + CHG_YMD > 검사유효기간종료일+31일 │
│ + 명의이전(11) 레코드 존재 │
│ → 조건 충족: 접수(01) │
└──────────────────────────────────────────────┘
│ (조건 미충족)
@ -222,22 +282,31 @@ existingData.setCarBscMttrInqSggNm(sggNm);
## 요약 정리
### 공통 로직
| Step | API 호출 | 입력 | 출력 | 용도 |
|------|---------|------|------|------|
| Step 0 | 자동차기본정보 | 차량번호 + 오늘일자 | step0Response (차대번호) | 현재 차량 기본 정보 |
| Step 1 | 자동차기본정보 | 차대번호 + 부과일자 | step1Response (소유자명, 회원번호) | 부과일자 기준 소유자 정보 |
### 처리상태코드 매핑
| 코드 | 상태명 | 처리 로직 | 클래스 |
|------|--------|--------------------------|--------|
| 02 | 상품용 | 부과일자 소유자가 상품용 + 명의이전(11) CHG_YMD <= 종료일+31일 | `ProductUseOmChecker` |
| 01 | 접수 | 검사유효기간종료일+31일 이후 명의이전 존재 | `OwnerTransferOmChecker` |
| 03 | 이첩 | 소유자 일치 + 법정동코드 불일치 | `TransferOmChecker` |
| 순서 | 코드 | 상태명 | 처리 로직 | 클래스 |
|------|------|--------|--------------------------|--------|
| 1 | 02 | 상품용 | step1 소유자가 상품용 + 명의이전(11) CHG_YMD <= 종료일+31일 | `ProductUseOmChecker` |
| 2 | 03 | 이첩 | step1/step2/step3 소유자 비교 + 법정동코드 불일치 | `TransferOmChecker` |
| 3 | 01 | 접수 | 검사유효기간종료일+31일 이후 명의이전 존재 | `OwnerTransferOmChecker` |
### 미필 vs 지연 비교
| 구분 | 미필 | 지연 |
|------|-----|------|
| 부과일자 | 검사유효기간 종료일 + 146일 | 검사일 |
| 상품용 조건 | 부과일자 기준 소유자명 | 검사일 기준 소유자명 |
| Step 1 기준일 | 부과일자 (종료일+146일) | 검사일 |
| 상품용 조건 | step1(부과일자) 기준 소유자명 | step1(검사일) 기준 소유자명 |
| Checker 개수 | 3개 | 7개 |
| 이첩 로직 | 3단계 API + 소유자 비교 | DAYCNT 기반 |
| 공통 로직 | Step 0, Step 1 | Step 0, Step 1 |
---
@ -249,6 +318,7 @@ existingData.setCarBscMttrInqSggNm(sggNm);
levyCrtrYmd = 검사유효기간 종료일 + 146일
// 처리상태코드
TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_01_RECEIPT = "01"
TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_02_PRODUCT_USE = "02"
TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_03_TRANSFER = "03"
@ -258,7 +328,7 @@ TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_03_TRANSFER = "03"
---
**문서 최종 수정일**: 2025-12-09
**실제 소스 코드 기준**: om_checker 폴더 내 Checker 클래스들
**분석 대상 클래스**: 3개 (ProductUseOmChecker, OwnerTransferOmChecker, TransferOmChecker)
**주요 변경사항**: 검사유효기간 종료일 + 31일 로직 적용
**문서 최종 수정일**: 2025-12-15
**실제 소스 코드 기준**: ComparisonOmServiceImpl, om_checker 폴더 내 Checker 클래스들
**분석 대상 클래스**: 4개 (ComparisonOmServiceImpl + 3개 Checker)
**주요 변경사항**: Step 0, Step 1 공통 로직 추가, 이첩 순서 변경 (3번→2번)

@ -5,14 +5,15 @@
자동차 과태료 부과 대상(지연)을 검증하기 위한 비교 로직 정의서입니다.
### 구현 위치
- **Main Service**: `src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/ComparisonServiceImpl.java`
- **Checker 클래스**: `src/main/java/go/kr/project/carInspectionPenalty/registration/service/impl/delay_checker/`
- `ProductUseChecker.java` - 1. 상품용(명의이전) : 상품용
- `ProductUseChnageChecker.java` - 1-1. 상품용(변경등록) : 상품용
- `ProductCloseWithin31Checker.java` - 2. 내사종결(명의이전 이전소유자 상품용, 31일 이내) : 명의이전(25.9.11.) 이전소유자 상품용
- `OwnerCloseWithin31Checker.java` - 3. 내사종결(순수 명의이전, 31일 이내) : 명의이전(25.8.28.)
- `ProductLevyOver31Checker.java` - 4. 날짜수정후부과(명의이전 이전소유자 상품용, 31일 초과) : 경기도 고양시/ 장준혁, 미수검명의이전(25.8.19.)
- `OwnerLevyOver31Checker.java` - 5. 날짜수정후부과(순수 명의이전, 31일 초과) : 대구광역시 달서구/ 하나캐피탈(주), 미수검명의이전(25.9.3.)
- `TransferCase115DayChecker.java` - 6. 이첩 : case 1 = 경상남도 창원시/ 현대캐피탈 주식회사, 115일 도래지 case 2 = 인천광역시 부평구/ (주)우리카드, 검사일사용본거지
- `TransferCase115DayChecker.java` - 4. 이첩 : case 1 = 경상남도 창원시/ 현대캐피탈 주식회사, 115일 도래지 case 2 = 인천광역시 부평구/ (주)우리카드, 검사일사용본거지
- `ProductLevyOver31Checker.java` - 5. 날짜수정후부과(명의이전 이전소유자 상품용, 31일 초과) : 경기도 고양시/ 장준혁, 미수검명의이전(25.8.19.)
- `OwnerLevyOver31Checker.java` - 6. 날짜수정후부과(순수 명의이전, 31일 초과) : 대구광역시 달서구/ 하나캐피탈(주), 미수검명의이전(25.9.3.)
### 기본 설정
- 비교로직에 사용되는 API: `ExternalVehicleApiServiceImpl.getBasicInfo`, `getLedgerInfo` 호출
@ -23,6 +24,7 @@
| 일자 | 변경 내용 | 비고 |
|------|----------|------|
| 2025-12-15 | Step 0, Step 1 공통 로직 추가 및 순서 변경 | 이첩 순서 변경 (6번→4번) |
| 2025-12-08 | delay_checker 소스 기준 전면 재작성 | 실제 코드와 일치하도록 정리 |
| 2025-12-03 | 실제 소스 코드 기준으로 전면 재작성 | Javadoc과 실제 로직 차이 명시 |
| 2025-12-02 | 내사종결 로직 추가 및 상품용 조건 변경 | 명의이전 31일 이내 조건 추가 |
@ -30,9 +32,51 @@
### 처리 규칙
> **중요**: 순서가 중요함!
> 1. 상품용(명의이전) → 1-1. 상품용(변경등록) → 2. 내사종결(상품용) → 3. 내사종결(명의이전) → 4. 날짜수정(상품용) → 5. 날짜수정(명의이전) → 6. 이첩
>
> **공통 로직 (한 번만 실행)**:
> - Step 0: 자동차기본정보 조회 (차량번호 + 오늘일자)
> - Step 1: 자동차기본정보 조회 (차대번호 + 검사일)
>
> **Checker 순서**:
> 1. 상품용(명의이전) → 1-1. 상품용(변경등록) → 2. 내사종결(상품용) → 3. 내사종결(명의이전) → 4. 이첩 → 5. 날짜수정(상품용) → 6. 날짜수정(명의이전)
> - 조건에 걸리는 순간 다음 차량번호 비교로 진행
> - 각 비교 로직별로 개별 API 호출 수행
> - 각 Checker는 공통 API 응답(step0Response, step1Response)을 파라미터로 받음
---
## 공통 로직 (ComparisonServiceImpl)
### Step 0: 자동차기본정보 조회 (현재 차량 정보)
**API 호출**: `getBasicInfo`
| 입력 | 값 |
|------|-----|
| 차량번호 | `vhclno` (특수문자 '*' 제거) |
| 부과일자 | 오늘 날짜 (`LocalDate.now()`) |
**출력**:
- `step0Response` → 모든 Checker에 전달
- 주요 필드: `vin` (차대번호)
**실패 시**: 비교 로직 종료 (return null)
---
### Step 1: 자동차기본정보 조회 (검사일 기준 정보)
**API 호출**: `getBasicInfo`
| 입력 | 값 |
|------|-----|
| 차대번호 | `step0Response.vin` |
| 부과일자 | 검사일 (`inspYmd`) |
**출력**:
- `step1Response` → 모든 Checker에 전달
- 주요 필드: `소유자명`, `대표소유자회원번호`
**실패 시**: 비교 로직 종료 (return null)
---
@ -43,19 +87,20 @@
**처리상태코드**: `02` (상품용)
**클래스**: `ProductUseChecker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사일` | `차대번호(vin)`, `소유자명`, `대표소유자회원번호` | 검사일 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
**참고**: Step 0, Step 1은 공통 로직에서 이미 호출됨
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") ← 상품용 아니면 return null
1. step1Response 소유자명.contains("상품용") ← 상품용 아니면 return null
2. 갑부에서 명의이전(11) 레코드 찾기
- CHG_TASK_SE_CD == "11"
@ -63,7 +108,7 @@
- 가장 마지막 일자 선택
← 없으면 return null
3. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
3. Step4 대표소유자회원번호 == step1Response 대표소유자회원번호
← 불일치면 return null
→ 모든 조건 충족: 상품용(02) 처리
@ -85,19 +130,18 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
**처리상태코드**: `02` (상품용)
**클래스**: `ProductUseChnageChecker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사일` | `차대번호(vin)`, `소유자명`, `대표소유자회원번호` | 검사일 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 변경등록 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 변경등록 시점 소유자 확인 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 변경등록 시점 소유자 확인 |
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") ← 상품용 아니면 return null
1. step1Response 소유자명.contains("상품용") ← 상품용 아니면 return null
2. 갑부에서 변경등록(21) 레코드 찾기
- CHG_TASK_SE_CD == "21"
@ -106,7 +150,7 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
- 가장 마지막 일자 선택
← 없으면 return null
3. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
3. Step4 대표소유자회원번호 == step1Response 대표소유자회원번호
← 불일치면 return null
→ 모든 조건 충족: 상품용(02) 처리
@ -128,20 +172,19 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
**처리상태코드**: `04` (내사종결)
**클래스**: `ProductCloseWithin31Checker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사일` | `차대번호`, `소유자명` | 검사일 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD-1일` | `소유자명` | 명의이전 직전 소유자 확인 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD-1일` | `소유자명` | 명의이전 직전 소유자 확인 |
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
!Step1 소유자명.contains("상품용") → 계속 진행
1. step1Response 소유자명.contains("상품용") → return null (1번에서 처리됨)
!step1Response 소유자명.contains("상품용") → 계속 진행
2. 갑부에서 명의이전(11) 레코드 찾기
- CHG_TASK_SE_CD == "11"
@ -151,7 +194,7 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
3. 일수 계산: 명의이전일자 ~ 검사일
- 0~31일 이내 → 계속 진행
- 31일 초과 → return null (4번에서 처리)
- 31일 초과 → return null (5번에서 처리)
4. Step4 소유자명.contains("상품용")
← 상품용 아니면 return null
@ -175,20 +218,19 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
**처리상태코드**: `04` (내사종결)
**클래스**: `OwnerCloseWithin31Checker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사일` | `차대번호`, `소유자명`, `대표소유자회원번호` | 검사일 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
!Step1 소유자명.contains("상품용") → 계속 진행
1. step1Response 소유자명.contains("상품용") → return null (1번에서 처리됨)
!step1Response 소유자명.contains("상품용") → 계속 진행
2. 갑부에서 명의이전(11) 레코드 찾기
- CHG_TASK_SE_CD == "11"
@ -198,9 +240,9 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
3. 일수 계산: 명의이전일자 ~ 검사일
- 0~31일 이내 → 계속 진행
- 31일 초과 → return null (5번에서 처리)
- 31일 초과 → return null (6번에서 처리)
4. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
4. Step4 대표소유자회원번호 == step1Response 대표소유자회원번호
← 불일치면 return null
→ 모든 조건 충족: 내사종결(04) 처리
@ -217,25 +259,72 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
---
### 4. 날짜수정후부과 - 명의이전 이전소유자 상품용, 31일 초과 (`ProductLevyOver31Checker`)
### 4. 이첩 검증 (`TransferCase115DayChecker`)
**처리상태코드**: `03` (이첩)
**클래스**: `TransferCase115DayChecker.java`
#### 추가 API 호출
| API | 입력 파라미터 | 출력 데이터 | 용도 |
|-----|--------------|-------------|------|
| 자동차기본정보 | `차량번호`, `부과일자=부과기준일` | `사용본거지법정동코드` | 부과기준일 기준 사용본거지 확인 |
**참고**: Step 0, Step 1은 공통 로직에서 이미 호출됨
#### 비교 조건
```
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 업데이트 필드
```java
existingData.setTaskPrcsSttsCd("03"); // 이첩
existingData.setCarBscMttrInqFlnm(existingData.getOwnrNm()); // 기존 소유자명 유지
existingData.setCarBscMttrInqSggCd(sggCd);
existingData.setCarBscMttrInqSggNm(sggNm);
```
---
### 5. 날짜수정후부과 - 명의이전 이전소유자 상품용, 31일 초과 (`ProductLevyOver31Checker`)
**처리상태코드**: `05` (날짜 수정 후 부과)
**클래스**: `ProductLevyOver31Checker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사일` | `차대번호`, `소유자명` | 검사일 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD-1일` | `소유자명` | 명의이전 직전 소유자 확인 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD-1일` | `소유자명` | 명의이전 직전 소유자 확인 |
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
!Step1 소유자명.contains("상품용") → 계속 진행
1. step1Response 소유자명.contains("상품용") → return null (1번에서 처리됨)
!step1Response 소유자명.contains("상품용") → 계속 진행
2. 갑부에서 명의이전(11) 레코드 찾기
- CHG_TASK_SE_CD == "11"
@ -264,25 +353,24 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
---
### 5. 날짜수정후부과 - 순수 명의이전, 31일 초과 (`OwnerLevyOver31Checker`)
### 6. 날짜수정후부과 - 순수 명의이전, 31일 초과 (`OwnerLevyOver31Checker`)
**처리상태코드**: `05` (날짜 수정 후 부과)
**클래스**: `OwnerLevyOver31Checker.java`
#### API 호출 순서
#### 추가 API 호출 순서
| 순서 | API | 입력 파라미터 | 출력 데이터 | 용도 |
|------|-----|--------------|-------------|------|
| 1 | 자동차기본정보 | `차량번호`, `부과일자=검사일` | `차대번호`, `소유자명`, `대표소유자회원번호` | 검사일 기준 소유자 확인 |
| 2 | 자동차기본정보 | `1.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 2 | 자동차기본정보 | `step0.차대번호`, `부과일자=오늘` | `차량번호`, `성명`, `주민번호`, `법정동코드` | 현재 소유자 정보 |
| 3 | 자동차등록원부(갑) | `2.차량번호`, `2.성명`, `2.주민번호`, `2.법정동코드` | 갑부 상세 List | 명의이전 이력 조회 |
| 4 | 자동차기본정보 | `1.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
| 4 | 자동차기본정보 | `step0.차대번호`, `부과일자=CHG_YMD` | `소유자명`, `대표소유자회원번호` | 명의이전 시점 소유자 확인 |
#### 비교 조건
```
1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨)
!Step1 소유자명.contains("상품용") → 계속 진행
1. step1Response 소유자명.contains("상품용") → return null (1번에서 처리됨)
!step1Response 소유자명.contains("상품용") → 계속 진행
2. 갑부에서 명의이전(11) 레코드 찾기
- CHG_TASK_SE_CD == "11"
@ -294,7 +382,7 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd());
- 31일 초과 → 계속 진행
- 0~31일 이내 → return null (3번에서 처리)
4. Step4 대표소유자회원번호 == Step1 대표소유자회원번호
4. Step4 대표소유자회원번호 == step1Response 대표소유자회원번호
← 불일치면 return null
→ 모든 조건 충족: 날짜수정후부과(05) 처리
@ -311,52 +399,6 @@ 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 업데이트 필드
```java
existingData.setTaskPrcsSttsCd("03"); // 이첩
existingData.setCarBscMttrInqFlnm(existingData.getOwnrNm()); // 기존 소유자명 유지
existingData.setCarBscMttrInqSggCd(sggCd);
existingData.setCarBscMttrInqSggNm(sggNm);
```
---
## 처리 흐름도
```
@ -367,8 +409,20 @@ existingData.setCarBscMttrInqSggNm(sggNm);
┌──────────────────────────────────────────────┐
│ 공통: Step 0 - 자동차기본정보 (차량번호, 오늘) │
│ → step0Response (차대번호) │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ 공통: Step 1 - 자동차기본정보 (차대번호, 검사일)│
│ → step1Response (소유자명) │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ 1. 상품용-명의이전 (ProductUseChecker) │
│ 조건: 검사일 소유자명.contains("상품용") │
│ 조건: step1 소유자명.contains("상품용")
│ + 명의이전(11) 레코드 존재 │
│ → 조건 충족: 상품용(02) │
└──────────────────────────────────────────────┘
@ -376,7 +430,7 @@ existingData.setCarBscMttrInqSggNm(sggNm);
┌──────────────────────────────────────────────┐
│ 1-1. 상품용-변경등록 (ProductUseChnageChecker)│
│ 조건: 검사일 소유자명.contains("상품용")
│ 조건: step1 소유자명.contains("상품용")
│ + 변경등록(21) + 성명변경 포함 │
│ → 조건 충족: 상품용(02) │
└──────────────────────────────────────────────┘
@ -397,23 +451,23 @@ existingData.setCarBscMttrInqSggNm(sggNm);
│ (조건 미충족)
┌──────────────────────────────────────────────┐
│ 4. 날짜수정-상품용 (ProductLevyOver31Checker)
│ 조건: 31일 초과 + 명의이전 전 상품용
│ → 조건 충족: 날짜수정후부과(05)
│ 4. 이첩 (TransferCase115DayChecker)
│ 조건: 법정동코드 앞4자리 != 조직코드 앞4자리
│ → 조건 충족: 이첩(03)
└──────────────────────────────────────────────┘
│ (조건 미충족)
┌──────────────────────────────────────────────┐
│ 5. 날짜수정-명의이전 (OwnerLevyOver31Checker) │
│ 조건: 31일 초과 + 동일 소유자
│ 5. 날짜수정-상품용 (ProductLevyOver31Checker) │
│ 조건: 31일 초과 + 명의이전 전 상품용
│ → 조건 충족: 날짜수정후부과(05) │
└──────────────────────────────────────────────┘
│ (조건 미충족)
┌──────────────────────────────────────────────┐
│ 6. 이첩 (TransferCase115DayChecker)
│ 조건: 법정동코드 앞4자리 != 조직코드 앞4자리
│ → 조건 충족: 이첩(03)
│ 6. 날짜수정-명의이전 (OwnerLevyOver31Checker)
│ 조건: 31일 초과 + 동일 소유자
│ → 조건 충족: 날짜수정후부과(05)
└──────────────────────────────────────────────┘
│ (조건 미충족)
@ -424,25 +478,32 @@ existingData.setCarBscMttrInqSggNm(sggNm);
## 요약 정리
### 공통 로직
| Step | API 호출 | 입력 | 출력 | 용도 |
|------|---------|------|------|------|
| Step 0 | 자동차기본정보 | 차량번호 + 오늘일자 | step0Response (차대번호) | 현재 차량 기본 정보 |
| Step 1 | 자동차기본정보 | 차대번호 + 검사일 | step1Response (소유자명, 회원번호) | 검사일 기준 소유자 정보 |
### 처리상태코드 매핑
| 코드 | 상태명 | 처리 로직 | 클래스 |
|------|--------|----------|--------|
| 02 | 상품용 | 검사일 소유자가 상품용 + 명의이전(11) | `ProductUseChecker` |
| 02 | 상품용 | 검사일 소유자가 상품용 + 변경등록(21) + 성명변경 | `ProductUseChnageChecker` |
| 04 | 내사종결 | 명의이전 전 상품용 (31일 이내) | `ProductCloseWithin31Checker` |
| 04 | 내사종결 | 순수 명의이전 (31일 이내) | `OwnerCloseWithin31Checker` |
| 05 | 날짜수정후부과 | 명의이전 전 상품용 (31일 초과) | `ProductLevyOver31Checker` |
| 05 | 날짜수정후부과 | 순수 명의이전 (31일 초과) | `OwnerLevyOver31Checker` |
| 03 | 이첩 | 법정동코드 불일치 | `TransferCase115DayChecker` |
| 순서 | 코드 | 상태명 | 처리 로직 | 클래스 |
|------|------|--------|----------|--------|
| 1 | 02 | 상품용 | step1 소유자가 상품용 + 명의이전(11) | `ProductUseChecker` |
| 1-1 | 02 | 상품용 | step1 소유자가 상품용 + 변경등록(21) + 성명변경 | `ProductUseChnageChecker` |
| 2 | 04 | 내사종결 | 명의이전 전 상품용 (31일 이내) | `ProductCloseWithin31Checker` |
| 3 | 04 | 내사종결 | 순수 명의이전 (31일 이내) | `OwnerCloseWithin31Checker` |
| 4 | 03 | 이첩 | 법정동코드 불일치 | `TransferCase115DayChecker` |
| 5 | 05 | 날짜수정후부과 | 명의이전 전 상품용 (31일 초과) | `ProductLevyOver31Checker` |
| 6 | 05 | 날짜수정후부과 | 순수 명의이전 (31일 초과) | `OwnerLevyOver31Checker` |
### 상품용 vs 순수 명의이전 비교
| 구분 | 상품용 케이스 (2, 4번) | 순수 명의이전 케이스 (3, 5번) |
| 구분 | 상품용 케이스 (2, 5번) | 순수 명의이전 케이스 (3, 6번) |
|------|----------------------|----------------------------|
| 검사일 소유자 | 상품용 아님 | 상품용 아님 |
| 명의이전 직전 소유자 | 상품용 **포함** | 소유자 회원번호 **일치** |
| Step 4 확인사항 | 소유자명.contains("상품용") | 대표소유자회원번호 == Step1 |
| Step 4 확인사항 | 소유자명.contains("상품용") | 대표소유자회원번호 == step1 |
| 갑부 검색 조건 | CHG_YMD <= 검사일 | 유효기간만료일-90일 <= CHG_YMD <= 검사종료일자 |
| 일수 기준 | 31일 이내/초과 | 31일 이내/초과 |
| 처리상태코드 | 31일 이내: 04, 초과: 05 | 31일 이내: 04, 초과: 05 |
@ -469,6 +530,7 @@ TaskPrcsSttsConstants.TASK_PRCS_STTS_CD_05_DATE_MODIFIED_LEVY = "05"
---
**문서 작성 완료일**: 2025-12-08
**실제 소스 코드 기준**: delay_checker 폴더 내 Checker 클래스들
**분석 대상 클래스**: 7개 (ProductUseChecker, ProductUseChnageChecker, ProductCloseWithin31Checker, OwnerCloseWithin31Checker, ProductLevyOver31Checker, OwnerLevyOver31Checker, TransferCase115DayChecker)
**문서 최종 수정일**: 2025-12-15
**실제 소스 코드 기준**: ComparisonServiceImpl, delay_checker 폴더 내 Checker 클래스들
**분석 대상 클래스**: 8개 (ComparisonServiceImpl + 7개 Checker)
**주요 변경사항**: Step 0, Step 1 공통 로직 추가, 이첩 순서 변경 (6번→4번)

Loading…
Cancel
Save