From fb120ed4a5cd622427b63e84a8d0321a12073048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EC=98=81?= Date: Tue, 9 Dec 2025 13:26:42 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DB/DDL/vips/seq_car_ffnlg_trgt_incmp_id.sql | 4 +-- docs/자동차과태료_비교로직_정리-[미필].md | 28 ++++++++--------- .../java/egovframework/util/DateUtil.java | 30 +++++++++++++++---- .../CarFfnlgTrgtIncmpController.java | 10 +++++++ .../impl/ComparisonOmRemarkBuilder.java | 8 ++--- .../om_checker/OwnerTransferOmChecker.java | 14 +++++++-- .../impl/om_checker/ProductUseOmChecker.java | 10 ++++++- .../impl/om_checker/TransferOmChecker.java | 4 +-- .../registrationOm/list.jsp | 4 +-- 9 files changed, 78 insertions(+), 34 deletions(-) diff --git a/DB/DDL/vips/seq_car_ffnlg_trgt_incmp_id.sql b/DB/DDL/vips/seq_car_ffnlg_trgt_incmp_id.sql index f552aae..1df4e12 100644 --- a/DB/DDL/vips/seq_car_ffnlg_trgt_incmp_id.sql +++ b/DB/DDL/vips/seq_car_ffnlg_trgt_incmp_id.sql @@ -7,7 +7,7 @@ DROP SEQUENCE IF EXISTS seq_car_ffnlg_trgt_incmp_id; -- 시퀀스 생성 CREATE SEQUENCE seq_car_ffnlg_trgt_incmp_id - START WITH 1 + START WITH 1000 INCREMENT BY 1 MINVALUE 1 - MAXVALUE 99999999999999999999; + MAXVALUE 99999999999999999; diff --git a/docs/자동차과태료_비교로직_정리-[미필].md b/docs/자동차과태료_비교로직_정리-[미필].md index 4a6657f..57df33f 100644 --- a/docs/자동차과태료_비교로직_정리-[미필].md +++ b/docs/자동차과태료_비교로직_정리-[미필].md @@ -104,10 +104,10 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd()); ← 없으면 return null 3. Step4 소유자명 확인 - - "상품용" 포함 → 상품용(02) - - "상품용" 미포함 → 상품용(02) + - "상품용" 포함 → 접수(01) + - "상품용" 미포함 → 접수(01) -→ 모든 조건 충족: 상품용(02) 처리 +→ 모든 조건 충족: 접수(01) 처리 ``` #### 결과 분기 @@ -147,13 +147,13 @@ existingData.setCarRegFrmbkChgYmd(targetRecord.getChgYmd()); 1. Step1 소유자명.contains("상품용") → return null (1번에서 처리됨) !Step1 소유자명.contains("상품용") → 계속 진행 -2. Step1 소유자회원번호 == Step2 소유자회원번호 - ← 동일하면 return null +2. Step1 소유자회원번호 != Step2 소유자회원번호 + ← 불일치면 return null -3. Step1 소유자회원번호 == Step3 소유자회원번호 - ← 동일하면 return null +3. Step1 소유자회원번호 != Step3 소유자회원번호 + ← 불일치면 return null -4. 법정동코드 앞 4자리 != 사용자 조직코드 앞 4자리 +4. 법정동코드 앞 4자리 == 사용자 조직코드 앞 4자리 ← 일치하면 return null → 불일치: 이첩(03) 처리 @@ -205,8 +205,8 @@ existingData.setCarBscMttrInqSggNm(sggNm); ┌──────────────────────────────────────────────┐ │ 3. 이첩 (TransferOmChecker) │ │ 조건: 소유자명에 상품용 미포함 │ -│ + 1단계/2단계 소유자 다름 │ -│ + 1단계/3단계 소유자 다름 │ +│ + 1단계/2단계 소유자 같음 │ +│ + 1단계/3단계 소유자 같음 │ │ + 법정동코드 앞4자리 != 조직코드 앞4자리│ │ → 조건 충족: 이첩(03) │ └──────────────────────────────────────────────┘ @@ -221,11 +221,11 @@ existingData.setCarBscMttrInqSggNm(sggNm); ### 처리상태코드 매핑 -| 코드 | 상태명 | 처리 로직 | 클래스 | -|------|--------|----------|--------| +| 코드 | 상태명 | 처리 로직 | 클래스 | +|------|--------|--------------------------|--------| | 02 | 상품용 | 부과일자 소유자가 상품용 + 명의이전(11) | `ProductUseOmChecker` | -| 02 | 상품용 | 검사유효기간종료일 이후 명의이전 존재 | `OwnerTransferOmChecker` | -| 03 | 이첩 | 소유자 변동 + 법정동코드 불일치 | `TransferOmChecker` | +| 02 | 상품용 | 검사유효기간종료일 이후 명의이전 존재 | `OwnerTransferOmChecker` | +| 03 | 이첩 | 소유자 일치 + 법정동코드 불일치 | `TransferOmChecker` | ### 미필 vs 지연 비교 diff --git a/src/main/java/egovframework/util/DateUtil.java b/src/main/java/egovframework/util/DateUtil.java index 5c85817..77fed10 100644 --- a/src/main/java/egovframework/util/DateUtil.java +++ b/src/main/java/egovframework/util/DateUtil.java @@ -229,21 +229,39 @@ public class DateUtil { } /** - * 날짜를 짧은 형식으로 변환 (YYYYMMDD -> YY.M.D) + * 날짜를 짧은 형식으로 변환 (YYYYMMDD 또는 YYYY-MM-DD -> YY.M.D) * 예: 20250903 -> 25.9.3 + * 예: 2025-09-03 -> 25.9.3 * - * @param dateStr 날짜 문자열 (yyyyMMdd 형식) + * @param dateStr 날짜 문자열 (yyyyMMdd 또는 yyyy-MM-dd 형식) * @return YY.M.D 형식의 날짜 문자열, 변환 실패 시 원본 문자열 반환 */ public static String formatToShortDate(String dateStr) { - if (dateStr == null || dateStr.length() != 8) { + if (dateStr == null) { return dateStr; } try { - String year = dateStr.substring(2, 4); // YY - int month = Integer.parseInt(dateStr.substring(4, 6)); // M (앞의 0 제거) - int day = Integer.parseInt(dateStr.substring(6, 8)); // D (앞의 0 제거) + String trimmed = dateStr.trim(); + String year, monthStr, dayStr; + + if (trimmed.length() == 8) { + // YYYYMMDD 형식 + year = trimmed.substring(2, 4); // YY + monthStr = trimmed.substring(4, 6); // MM + dayStr = trimmed.substring(6, 8); // DD + } else if (trimmed.length() == 10) { + // YYYY-MM-DD 형식 + year = trimmed.substring(2, 4); // YY + monthStr = trimmed.substring(5, 7); // MM + dayStr = trimmed.substring(8, 10); // DD + } else { + // 그 외 형식은 원본 반환 + return dateStr; + } + + int month = Integer.parseInt(monthStr); // M (앞의 0 제거) + int day = Integer.parseInt(dayStr); // D (앞의 0 제거) return year + "." + month + "." + day; } catch (Exception e) { diff --git a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/controller/CarFfnlgTrgtIncmpController.java b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/controller/CarFfnlgTrgtIncmpController.java index 53fe361..f3678a7 100644 --- a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/controller/CarFfnlgTrgtIncmpController.java +++ b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/controller/CarFfnlgTrgtIncmpController.java @@ -77,6 +77,16 @@ public class CarFfnlgTrgtIncmpController { .sortAscending(true) .build(); model.addAttribute("ffnlgTrgtSeCdList", commonCodeService.selectCodeDetailList(ffnlgTrgtSeCdSearchVO)); + + // 부과 기준일자 코드 조회 (공통코드) + CmmnCodeSearchVO omDayCdSearchVO = CmmnCodeSearchVO.builder() + .searchCdGroupId("OM_DAY_CD") + .searchCdId("D") + .searchUseYn("Y") + .sortColumn("SORT_ORDR") + .sortAscending(true) + .build(); + model.addAttribute("omDayCdVO", commonCodeService.selectCodeDetailList(omDayCdSearchVO).get(0)); return "carInspectionPenalty/registrationOm/list" + TilesConstants.BASE; } diff --git a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/ComparisonOmRemarkBuilder.java b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/ComparisonOmRemarkBuilder.java index fd58858..32f6a7f 100644 --- a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/ComparisonOmRemarkBuilder.java +++ b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/ComparisonOmRemarkBuilder.java @@ -152,8 +152,8 @@ public class ComparisonOmRemarkBuilder { // 여섯째 줄: 상품용 일자 (명의이전 일자와 동일) sb.append(" - 상품용: ").append(DateUtil.formatDateString(ledgerRecord.getChgYmd())).append("\n"); - // 일곱째 줄: 일수차이 - sb.append("일수차이: ").append(daysBetween).append("일"); + // 일곱째 줄: 일수차이, 미필은 일수차이 제외 + //sb.append("일수차이: ").append(daysBetween).append("일"); return sb.toString(); } @@ -210,8 +210,8 @@ public class ComparisonOmRemarkBuilder { // 다섯째 줄: 명의이전 일자 sb.append(" - 명의이전: ").append(DateUtil.formatDateString(ledgerRecord.getChgYmd())).append("\n"); - // 일곱째 줄: 일수차이 - sb.append("일수차이: ").append(daysBetween).append("일"); + // 일곱째 줄: 일수차이, 미필은 일수차이 제외 + // sb.append("일수차이: ").append(daysBetween).append("일"); return sb.toString(); } diff --git a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/OwnerTransferOmChecker.java b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/OwnerTransferOmChecker.java index 1f5b999..0e8b5f1 100644 --- a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/OwnerTransferOmChecker.java +++ b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/OwnerTransferOmChecker.java @@ -37,8 +37,8 @@ import java.util.List; * • 명의이전 중 마지막 일자 * • CHG_TASK_SE_CD == "11" (명의이전) * - 3단계: 4번 API 소유자명 확인 - * • "상품용" 미포함 → 날짜수정후부과(05), 비고: 명의이전(날짜) - * • "상품용" 포함 → 내사종결(04), 비고: 명의이전(날짜) 이전소유자 상품용 + * • "상품용" 미포함 → 비고: 명의이전(날짜) + * • "상품용" 포함 → 비고: 명의이전(날짜) 이전소유자 상품용 */ @Slf4j @Component @@ -63,7 +63,15 @@ public class OwnerTransferOmChecker extends AbstractComparisonOmChecker { if (inspVldPrd != null && inspVldPrd.contains("~")) { String[] dates = inspVldPrd.split("~"); inspVldPrdStart = dates[0].trim().replace("-", ""); - inspVldPrdEnd = dates.length > 1 ? dates[1].trim().replace("-", "") : null; + + // 종료일 + 31일 계산 + if (dates.length > 1) { + String endDateStr = dates[1].trim().replace("-", ""); + LocalDate endDate = DateUtil.parseDate(endDateStr); + if (endDate != null) { + inspVldPrdEnd = DateUtil.formatLocalDate(endDate.plusDays(31), "yyyyMMdd"); + } + } } if (inspVldPrdEnd == null) { diff --git a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/ProductUseOmChecker.java b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/ProductUseOmChecker.java index d09ff64..d6523dd 100644 --- a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/ProductUseOmChecker.java +++ b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/ProductUseOmChecker.java @@ -48,7 +48,15 @@ public class ProductUseOmChecker extends AbstractComparisonOmChecker { if (inspVldPrd != null && inspVldPrd.contains("~")) { String[] dates = inspVldPrd.split("~"); inspVldPrdStart = dates[0].trim().replace("-", ""); - inspVldPrdEnd = dates.length > 1 ? dates[1].trim().replace("-", "") : null; + + // 종료일 + 31일 계산 + if (dates.length > 1) { + String endDateStr = dates[1].trim().replace("-", ""); + LocalDate endDate = DateUtil.parseDate(endDateStr); + if (endDate != null) { + inspVldPrdEnd = DateUtil.formatLocalDate(endDate.plusDays(31), "yyyyMMdd"); + } + } } try { diff --git a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/TransferOmChecker.java b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/TransferOmChecker.java index 99f9722..212f88d 100644 --- a/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/TransferOmChecker.java +++ b/src/main/java/go/kr/project/carInspectionPenalty/registrationOm/service/impl/om_checker/TransferOmChecker.java @@ -114,7 +114,7 @@ public class TransferOmChecker extends AbstractComparisonOmChecker { log.info("[이첩-미필] 2단계 - 소유자명: {}", step2RprsOwnrNm); // 2단계 비교: 1단계 소유자 = 2단계 소유자 동일 체크 - if (step1RprsvOwnrIdecno != null && step1RprsvOwnrIdecno.equals(step2RprsvOwnrIdecno)) { + if (step1RprsvOwnrIdecno != null && !step1RprsvOwnrIdecno.equals(step2RprsvOwnrIdecno)) { log.debug("[이첩-미필] 1단계와 2단계 소유자 동일 - 차량번호: {}, 소유자: {}", vhclno, step1RprsOwnrNm); return null; } @@ -139,7 +139,7 @@ public class TransferOmChecker extends AbstractComparisonOmChecker { log.info("[이첩-미필] 3단계 - 소유자명: {}", step3RprsOwnrNm); // 3단계 비교: 1단계 소유자 = 3단계 소유자 동일 체크 - if (step1RprsvOwnrIdecno != null && step1RprsvOwnrIdecno.equals(step3RprsvOwnrIdecno)) { + if (step1RprsvOwnrIdecno != null && !step1RprsvOwnrIdecno.equals(step3RprsvOwnrIdecno)) { log.debug("[이첩-미필] 1단계와 3단계 소유자 동일 - 차량번호: {}, 소유자: {}", vhclno, step1RprsOwnrNm); return null; } diff --git a/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp b/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp index 7a19e05..67ac891 100644 --- a/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp +++ b/src/main/webapp/WEB-INF/views/carInspectionPenalty/registrationOm/list.jsp @@ -832,7 +832,7 @@ return; } - if (!confirm(checkedRows.length + "건의 데이터에 대해 API를 호출하고 비교하시겠습니까?\n(미필: 부과일자 = 검사유효기간 종료일 + 145일)")) { + if (!confirm(checkedRows.length + "건의 데이터에 대해 API를 호출하고 비교하시겠습니까?\n(미필: 부과일자 = 검사유효기간 종료일 + ${omDayCdVO.cdNm})")) { return; } @@ -887,7 +887,7 @@ return; } - if (!confirm("현재 검색조건의 전체 데이터에 대해 API를 호출하고 비교하시겠습니까?\n(미필: 부과일자 = 검사유효기간 종료일 + 145일)")) { + if (!confirm("현재 검색조건의 전체 데이터에 대해 API를 호출하고 비교하시겠습니까?\n(미필: 부과일자 = 검사유효기간 종료일 + ${omDayCdVO.cdNm})")) { return; }