전체적인 로직변경, 테이블 저장시 단독 트랜잭션으로 진행

에러 발생시에도 에러로그 남김
main
박성영 1 month ago
parent 193d6ef04c
commit c6a5057ab6

@ -0,0 +1,11 @@
-- 자동차 등록 원부(갑) 마스터 ID 시퀀스
-- CLFB000000000001, CLFB000000000002, ... 형태로 생성
CREATE SEQUENCE seq_car_ledger_frmbk
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 9999999999
CACHE 1000
NOCYCLE;
-- SELECT CONCAT('CLFB', LPAD(NEXTVAL(seq_car_ledger_frmbk), 16, '0'));

@ -0,0 +1,11 @@
-- 자동차 등록 원부(갑) 상세 ID 시퀀스
-- CLFD000000000001, CLFD000000000002, ... 형태로 생성
CREATE SEQUENCE seq_car_ledger_frmbk_dtl
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 9999999999
CACHE 1000
NOCYCLE;
-- SELECT CONCAT('CLFD', LPAD(NEXTVAL(seq_car_ledger_frmbk_dtl), 16, '0'));

@ -14,7 +14,7 @@ create table tb_car_bass_matter_inqire
DMND_VHRNO varchar(30) null comment '요청 자동차등록번호',
DMND_VIN varchar(17) null comment '요청 차대번호',
CNTC_RESULT_CODE varchar(8) null comment '연계 결과 코드',
CNTC_RESULT_DTLS varchar(200) null comment '연계 결과 상세',
CNTC_RESULT_DTLS varchar(4000) null comment '연계 결과 상세',
PRYE varchar(4) null comment '연식',
REGIST_DE varchar(8) null comment '등록일',
ERSR_REGIST_SE_CODE varchar(4) null comment '말소 등록 구분 코드',

@ -0,0 +1,87 @@
create table tb_car_ledger_frmbk
(
CAR_LEDGER_FRMBK_ID varchar(20) not null comment '자동차 등록 원부 갑 ID'
primary key,
INFO_SYS_ID varchar(6) null comment '정보 시스템 ID',
INFO_SYS_IP varchar(23) null comment '정보 시스템 IP',
SIGUNGU_CODE varchar(5) null comment '시군구 코드',
CNTC_INFO_CODE varchar(15) null comment '연계 정보 코드',
CHARGER_ID varchar(15) null comment '담당자 ID',
CHARGER_IP varchar(23) null comment '담당자 IP',
CHARGER_NM varchar(75) null comment '담당자명',
DMND_VHRNO varchar(30) null comment '요청 자동차등록번호',
DMND_ONES_INFORMATION_OPEN varchar(1) null comment '요청 개인 정보 공개',
DMND_CPTTR_NM varchar(75) null comment '요청 민원인 성명',
DMND_CPTTR_IHIDNUM varchar(100) null comment '요청 민원인 주민번호',
DMND_CPTTR_LEGALDONG_CODE varchar(10) null comment '요청 민원인 법정동 코드',
DMND_ROUTE_SE_CODE varchar(1) null comment '요청 경로 구분 코드',
DMND_DETAIL_EXPRESSION varchar(1) null comment '요청 내역 표시',
DMND_INQIRE_SE_CODE varchar(1) null comment '요청 조회 구분 코드',
CNTC_RESULT_CODE varchar(8) null comment '연계 결과 코드',
CNTC_RESULT_DTLS varchar(4000) null comment '연계 결과 상세',
LEDGER_GROUP_NO varchar(6) null comment '원부 그룹 번호',
LEDGER_INDVDLZ_NO varchar(6) null comment '원부 개별 번호',
VHMNO varchar(20) null comment '차량관리번호',
VHRNO varchar(30) null comment '차량등록번호',
VIN varchar(17) null comment '차대번호',
VHCTY_ASORT_CODE varchar(1) null comment '차종 종별 코드',
VHCTY_ASORT_NM varchar(30) null comment '차종 종별명',
CNM varchar(75) null comment '차명',
COLOR_CODE varchar(2) null comment '색상 코드',
COLOR_NM varchar(30) null comment '색상명',
NMPL_STNDRD_CODE varchar(1) null comment '번호판 규격 코드',
NMPL_STNDRD_NM varchar(30) null comment '번호판 규격명',
PRPOS_SE_CODE varchar(2) null comment '용도 구분 코드',
PRPOS_SE_NM varchar(20) null comment '용도 구분명',
MTRS_FOM_NM varchar(75) null comment '원동기 형식명',
FOM_NM varchar(75) null comment '형식명',
ACQS_AMOUNT varchar(50) null comment '취득 금액',
REGIST_DETAIL_CODE varchar(8) null comment '등록 상세 코드',
REGIST_DETAIL_NM varchar(30) null comment '등록 상세명',
FRST_REGIST_DE varchar(8) null comment '최초 등록일',
CAAG_ENDDE varchar(8) null comment '차령 종료일',
PRYE varchar(4) null comment '연식',
SPMNNO1 varchar(3) null comment '제원관리번호1',
SPMNNO2 varchar(14) null comment '제원관리번호2',
YBL_MD varchar(8) null comment '제작 년월일',
TRVL_DSTNC varchar(10) null comment '주행 거리',
INSPT_VALID_PD_BGNDE varchar(8) null comment '검사 유효 기간 시작일',
INSPT_VALID_PD_ENDDE varchar(8) null comment '검사 유효 기간 종료일',
CHCK_VALID_PD_BGNDE varchar(8) null comment '점검 유효 기간 시작일',
CHCK_VALID_PD_ENDDE varchar(8) null comment '점검 유효 기간 종료일',
REGIST_REQST_SE_NM varchar(75) null comment '등록 신청 구분명',
FRST_REGIST_RQRCNO varchar(20) null comment '최초 등록 접수번호',
NMPL_CSDY_REMNR_DE varchar(8) null comment '번호판 영치 최고일',
NMPL_CSDY_AT varchar(1) null comment '번호판 영치 여부',
BSS_USE_PD varchar(30) null comment '사업용 사용 기간',
OCTHT_ERSR_PRVNTC_NTICE_DE varchar(8) null comment '직권 말소 예고 통지일',
ERSR_REGIST_DE varchar(8) null comment '말소 등록일',
ERSR_REGIST_SE_CODE varchar(4) null comment '말소 등록 구분 코드',
ERSR_REGIST_SE_NM varchar(200) null comment '말소 등록 구분명',
MRTGCNT varchar(4) null comment '저당수',
VHCLECNT varchar(4) null comment '압류건수',
STMDCNT varchar(4) null comment '구조변경수',
ADRES1 varchar(750) null comment '사용 본거지 주소',
ADRES_NM1 varchar(300) null comment '사용 본거지 주소상세',
ADRES varchar(750) null comment '소유자 주소',
ADRES_NM varchar(300) null comment '소유자 주소상세',
INDVDL_BSNM_AT varchar(1) null comment '개인 사업자 여부',
TELNO varchar(30) null comment '대표소유자 전화번호',
MBER_NM varchar(75) null comment '대표소유자 성명',
MBER_SE_CODE varchar(2) null comment '대표소유자 회원 구분 코드',
MBER_SE_NO varchar(100) null comment '대표소유자 회원 번호',
TAXXMPT_TRGTER_SE_CODE varchar(2) null comment '비과세 대상 구분 코드',
TAXXMPT_TRGTER_SE_CODE_NM varchar(30) null comment '비과세 대상 구분 코드명',
CNT_MATTER varchar(5) null comment '특기사항 건수',
EMD_NM varchar(75) null comment '사용 본거지 행정동명',
PRVNTCCNT varchar(4) null comment '예고수',
XPORT_FLFL_AT_STTEMNT_DE varchar(8) null comment '수출 이행 여부 신고일',
PARTN_RQRCNO varchar(13) null comment '발급번호',
FRST_TRNSFR_DE varchar(8) null comment '최초 양도일',
PROCESS_IMPRTY_RESN_CODE varchar(2) null comment '처리 불가 사유 코드',
PROCESS_IMPRTY_RESN_DTLS varchar(200) null comment '처리 불가 사유 명세',
REG_DT datetime null comment '등록 일시',
RGTR varchar(11) null comment '등록자'
)
comment '자동차 등록 원부 갑';

@ -0,0 +1,23 @@
create table tb_car_ledger_frmbk_dtl
(
CAR_LEDGER_FRMBK_DTL_ID varchar(20) not null comment '자동차 등록 원부 갑 상세 ID'
primary key,
CAR_LEDGER_FRMBK_ID varchar(20) null comment '자동차 등록 원부 갑 ID',
MAINCHK varchar(2) null comment '해제여부',
CHANGE_JOB_SE_CODE varchar(2) null comment '변경 업무 구분 코드',
MAINNO varchar(4) null comment '주번호',
SUBNO varchar(4) null comment '부번호',
DTLS varchar(2000) null comment '사항란',
RQRCNO varchar(20) null comment '접수번호',
VHMNO varchar(20) null comment '차량관리번호',
LEDGER_GROUP_NO varchar(6) null comment '원부 그룹 번호',
LEDGER_INDVDLZ_NO varchar(6) null comment '원부 개별 번호',
GUBUN_NM varchar(75) null comment '변경 업무 구분명',
CHANGE_DE varchar(8) null comment '변경 일자',
DETAIL_SN varchar(6) null comment '상세 순번',
FLAG varchar(3) null comment '표기여부',
REG_DT datetime null comment '등록 일시',
RGTR varchar(11) null comment '등록자'
)
comment '자동차 등록 원부 갑 상세';

@ -5,7 +5,8 @@ import com.vmis.interfaceapp.model.basic.BasicResponse;
import com.vmis.interfaceapp.model.common.Envelope;
import com.vmis.interfaceapp.model.ledger.LedgerRequest;
import com.vmis.interfaceapp.model.ledger.LedgerResponse;
import com.vmis.interfaceapp.service.VehicleInterfaceService;
import com.vmis.interfaceapp.service.CarBassMatterInqireService;
import com.vmis.interfaceapp.service.CarLedgerFrmbkService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
@ -41,7 +42,7 @@ import org.springframework.web.bind.annotation.*;
* <h3> :</h3>
* <ul>
* <li> (Thin) </li>
* <li> {@link com.vmis.interfaceapp.service.VehicleInterfaceService} </li>
* <li> </li>
* <li>Swagger/OpenAPI </li>
* </ul>
*
@ -54,7 +55,8 @@ import org.springframework.web.bind.annotation.*;
@Tag(name = "Vehicle Interfaces", description = "시군구연계 자동차 정보 연계 API")
public class VehicleInterfaceController {
private final VehicleInterfaceService vehicleService;
private final CarBassMatterInqireService carBassMatterInqireService;
private final CarLedgerFrmbkService carLedgerFrmbkService;
/**
@ -132,7 +134,7 @@ public class VehicleInterfaceController {
@org.springframework.web.bind.annotation.RequestBody Envelope<BasicRequest> envelope
) {
// 서비스에서 요청 보강/로깅/호출을 모두 오케스트레이션
return vehicleService.basic(envelope);
return carBassMatterInqireService.basic(envelope);
}
/**
@ -228,6 +230,6 @@ public class VehicleInterfaceController {
@org.springframework.web.bind.annotation.RequestBody Envelope<LedgerRequest> envelope
) {
// 서비스에서 요청 보강/호출을 오케스트레이션
return vehicleService.ledger(envelope);
return carLedgerFrmbkService.ledger(envelope);
}
}

@ -0,0 +1,28 @@
package com.vmis.interfaceapp.mapper;
import com.vmis.interfaceapp.model.ledger.CarLedgerFrmbkDtlVO;
import com.vmis.interfaceapp.model.ledger.CarLedgerFrmbkVO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* () Mapper
*/
@Mapper
public interface CarLedgerFrmbkMapper {
// ID 시퀀스
String selectNextCarLedgerFrmbkId();
String selectNextCarLedgerFrmbkDtlId();
// 마스터 INSERT/UPDATE/SELECT
int insertCarLedgerFrmbk(CarLedgerFrmbkVO vo);
int updateCarLedgerFrmbk(CarLedgerFrmbkVO vo);
CarLedgerFrmbkVO selectCarLedgerFrmbkById(String carLedgerFrmbkId);
// 상세 INSERT (단건)
int insertCarLedgerFrmbkDtl(CarLedgerFrmbkDtlVO vo);
// 편의: 상세 일괄 (MyBatis foreach를 XML에서 사용할 수도 있으나, 여기서는 단건 호출을 반복)
}

@ -1,5 +1,6 @@
package com.vmis.interfaceapp.model.basic;
import com.vmis.interfaceapp.model.common.Envelope;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -19,6 +20,126 @@ import java.time.LocalDateTime;
@AllArgsConstructor
public class CarBassMatterInqireVO {
// ==== Static factory/mapping methods (moved from Service) ====
public static CarBassMatterInqireVO fromRequest(BasicRequest request) {
return CarBassMatterInqireVO.builder()
.infoSysId(request.getInfoSysId())
.infoSysIp(request.getInfoSysIp())
.sigunguCode(request.getSigunguCode())
.cntcInfoCode(request.getCntcInfoCode())
.chargerId(request.getChargerId())
.chargerIp(request.getChargerIp())
.chargerNm(request.getChargerNm())
.dmndLevyStdde(request.getLevyStdde())
.dmndInqireSeCode(request.getInqireSeCode())
.dmndVhrno(request.getVhrno())
.dmndVin(request.getVin())
.rgtr("SYSTEM")
.build();
}
public static CarBassMatterInqireVO fromResponse(String id, Envelope<BasicResponse> envelope) {
if (envelope == null || envelope.getData() == null || envelope.getData().isEmpty()) return null;
BasicResponse response = envelope.getData().get(0);
CarBassMatterInqireVO.CarBassMatterInqireVOBuilder builder = CarBassMatterInqireVO.builder()
.carBassMatterInqire(id)
.cntcResultCode(response.getCntcResultCode())
.cntcResultDtls(response.getCntcResultDtls());
if (response.getRecord() != null && !response.getRecord().isEmpty()) {
BasicResponse.Record record = response.getRecord().get(0);
applyRecord(builder, record);
}
return builder.build();
}
private static void applyRecord(CarBassMatterInqireVO.CarBassMatterInqireVOBuilder builder, BasicResponse.Record record) {
builder
.prye(record.getPrye())
.registDe(record.getRegistDe())
.ersrRegistSeCode(record.getErsrRegistSeCode())
.ersrRegistSeNm(record.getErsrRegistSeNm())
.ersrRegistDe(record.getErsrRegistDe())
.registDetailCode(record.getRegistDetailCode())
.dsplvl(record.getDsplvl())
.useStrnghldLegaldongCode(record.getUseStrnghldLegaldongCode())
.useStrnghldAdstrdCode(record.getUseStrnghldAdstrdCode())
.useStrnghldMntn(record.getUseStrnghldMntn())
.useStrnghldLnbr(record.getUseStrnghldLnbr())
.useStrnghldHo(record.getUseStrnghldHo())
.useStrnghldAdresNm(record.getUseStrnghldAdresNm())
.useStrnghldRoadNmCode(record.getUseStrnghldRoadNmCode())
.usgsrhldUndgrndBuldSeCode(record.getUsgsrhldUndgrndBuldSeCode())
.useStrnghldBuldMainNo(record.getUseStrnghldBuldMainNo())
.useStrnghldBuldSubNo(record.getUseStrnghldBuldSubNo())
.usgsrhldAdresFull(record.getUsgsrhldAdresFull())
.mberSeCode(record.getMberSeCode())
.mberSeNo(record.getMberSeNo())
.mberNm(record.getMberNm())
.telno(record.getTelno())
.ownerLegaldongCode(record.getOwnerLegaldongCode())
.ownerAdstrdCode(record.getOwnerAdstrdCode())
.ownerMntn(record.getOwnerMntn())
.ownerLnbr(record.getOwnerLnbr())
.ownerHo(record.getOwnerHo())
.ownerAdresNm(record.getOwnerAdresNm())
.ownerRoadNmCode(record.getOwnerRoadNmCode())
.ownerUndgrndBuldSeCode(record.getOwnerUndgrndBuldSeCode())
.ownerBuldMainNo(record.getOwnerBuldMainNo())
.ownerBuldSubNo(record.getOwnerBuldSubNo())
.ownrWholaddr(record.getOwnerAdresFull())
.aftrVhrno(record.getAftrVhrno())
.useFuelCode(record.getUseFuelCode())
.prposSeCode(record.getPrposSeCode())
.mtrsFomNm(record.getMtrsFomNm())
.frntVhrno(record.getFrntVhrno())
.vhclno(record.getVhrno())
.vin(record.getVin())
.cnm(record.getCnm())
.vhcleTotWt(record.getVhcleTotWt())
.caagEndde(record.getCaagEndde())
.changeDe(record.getChangeDe())
.vhctyAsortCode(record.getVhctyAsortCode())
.vhctyTyCode(record.getVhctyTyCode())
.vhctySeCode(record.getVhctySeCode())
.mxmmLdg(record.getMxmmLdg())
.vhctyAsortNm(record.getVhctyAsortNm())
.vhctyTyNm(record.getVhctyTyNm())
.vhctySeNm(record.getVhctySeNm())
.frstRegistDe(record.getFrstRegistDe())
.fomNm(record.getFomNm())
.acqsDe(record.getAcqsDe())
.acqsEndDe(record.getAcqsEndDe())
.yblMd(record.getYblMd())
.transrRegistDe(record.getTransrRegistDe())
.spcfRegistSttusCode(record.getSpcfRegistSttusCode())
.colorNm(record.getColorNm())
.mrtgCo(record.getMrtgCo())
.seizrCo(record.getSeizrCo())
.stmdCo(record.getStmdCo())
.nmplCsdyAt(record.getNmplCsdyAt())
.nmplCsdyRemnrDe(record.getNmplCsdyRemnrDe())
.originSeCode(record.getOriginSeCode())
.nmplStndrdCode(record.getNmplStndrdCode())
.acqsAmount(record.getAcqsAmount())
.insptValidPdBgnde(record.getInsptValidPdBgnde())
.insptValidPdEndde(record.getInsptValidPdEndde())
.useStrnghldGrcCode(record.getUseStrnghldGrcCode())
.tkcarPscapCo(record.getTkcarPscapCo())
.spmnno(record.getSpmnno())
.trvlDstnc(record.getTrvlDstnc())
.frstRegistRqrcno(record.getFrstRegistRqrcno())
.vlntErsrPrvntcNticeDe(record.getVlntErsrPrvntcNticeDe())
.registInsttNm(record.getRegistInsttNm())
.processImprtyResnCode(record.getProcessImprtyResnCode())
.processImprtyResnDtls(record.getProcessImprtyResnDtls())
.cbdLt(record.getCbdLt())
.cbdBt(record.getCbdBt())
.cbdHg(record.getCbdHg())
.frstMxmmLdg(record.getFrstMxmmLdg())
.fuelCnsmpRt(record.getFuelCnsmpRt())
.elctyCmpndFuelCnsmpRt(record.getElctyCmpndFuelCnsmpRt());
}
/**
* ID (PK)
* : CBMI000000000001

@ -0,0 +1,72 @@
package com.vmis.interfaceapp.model.ledger;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
/**
* () VO
*
* <p>tb_car_ledger_frmbk_dtl </p>
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CarLedgerFrmbkDtlVO {
// ==== Static factory/mapping methods (moved from Service) ====
public static List<CarLedgerFrmbkDtlVO> listFromResponse(LedgerResponse res, String masterId) {
List<CarLedgerFrmbkDtlVO> list = new ArrayList<>();
if (res == null || res.getRecord() == null) return list;
for (LedgerResponse.Record r : res.getRecord()) {
CarLedgerFrmbkDtlVO vo = CarLedgerFrmbkDtlVO.builder()
.carLedgerFrmbkId(masterId)
.mainchk(r.getMainchk())
.changeJobSeCode(r.getChangeJobSeCode())
.mainno(r.getMainno())
.subno(r.getSubno())
.dtls(r.getDtls())
.rqrcno(r.getRqrcno())
.vhmno(r.getVhmno())
.ledgerGroupNo(r.getLedgerGroupNo())
.ledgerIndvdlzNo(r.getLedgerIndvdlzNo())
.gubunNm(r.getGubunNm())
.changeDe(r.getChangeDe())
.detailSn(r.getDetailSn())
.flag(r.getFlag())
.rgtr("SYSTEM")
.build();
list.add(vo);
}
return list;
}
// PK
private String carLedgerFrmbkDtlId;
// FK
private String carLedgerFrmbkId;
// 본문
private String mainchk;
private String changeJobSeCode;
private String mainno;
private String subno;
private String dtls;
private String rqrcno;
private String vhmno;
private String ledgerGroupNo;
private String ledgerIndvdlzNo;
private String gubunNm;
private String changeDe;
private String detailSn;
private String flag;
// 감사
private String rgtr;
}

@ -0,0 +1,192 @@
package com.vmis.interfaceapp.model.ledger;
import com.vmis.interfaceapp.model.ledger.LedgerResponse.Record;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* () VO
*
* <p>tb_car_ledger_frmbk </p>
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CarLedgerFrmbkVO {
// ==== Static factory/mapping methods (moved from Service) ====
public static CarLedgerFrmbkVO fromRequest(com.vmis.interfaceapp.model.ledger.LedgerRequest request) {
return CarLedgerFrmbkVO.builder()
.infoSysId(request.getInfoSysId())
.infoSysIp(request.getInfoSysIp())
.sigunguCode(request.getSigunguCode())
.cntcInfoCode(request.getCntcInfoCode())
.chargerId(request.getChargerId())
.chargerIp(request.getChargerIp())
.chargerNm(request.getChargerNm())
.dmndVhrno(request.getVhrno())
.rgtr("SYSTEM")
.build();
}
public static CarLedgerFrmbkVO fromResponseMaster(String id, com.vmis.interfaceapp.model.ledger.LedgerResponse res) {
return CarLedgerFrmbkVO.builder()
.carLedgerFrmbkId(id)
.cntcResultCode(res.getCntcResultCode())
.cntcResultDtls(res.getCntcResultDtls())
.ledgerGroupNo(res.getLedgerGroupNo())
.ledgerIndvdlzNo(res.getLedgerIndvdlzNo())
.vhmno(res.getVhmno())
.vhrno(res.getVhrno())
.vin(res.getVin())
.vhctyAsortCode(res.getVhctyAsortCode())
.vhctyAsortNm(res.getVhctyAsortNm())
.cnm(res.getCnm())
.colorCode(res.getColorCode())
.colorNm(res.getColorNm())
.nmplStndrdCode(res.getNmplStndrdCode())
.nmplStndrdNm(res.getNmplStndrdNm())
.prposSeCode(res.getPrposSeCode())
.prposSeNm(res.getPrposSeNm())
.mtrsFomNm(res.getMtrsFomNm())
.fomNm(res.getFomNm())
.acqsAmount(res.getAcqsAmount())
.registDetailCode(res.getRegistDetailCode())
.registDetailNm(res.getRegistDetailNm())
.frstRegistDe(res.getFrstRegistDe())
.caagEndde(res.getCaagEndde())
.prye(res.getPrye())
.spmnno1(res.getSpmnno1())
.spmnno2(res.getSpmnno2())
.yblMd(res.getYblMd())
.trvlDstnc(res.getTrvlDstnc())
.insptValidPdBgnde(res.getInsptValidPdBgnde())
.insptValidPdEndde(res.getInsptValidPdEndde())
.chckValidPdBgnde(res.getChckValidPdBgnde())
.chckValidPdEndde(res.getChckValidPdEndde())
.registReqstSeNm(res.getRegistReqstSeNm())
.frstRegistRqrcno(res.getFrstRegistRqrcno())
.nmplCsdyRemnrDe(res.getNmplCsdyRemnrDe())
.nmplCsdyAt(res.getNmplCsdyAt())
.bssUsePd(res.getBssUsePd())
.octhtErsrPrvntcNticeDe(res.getOcthtErsrPrvntcNticeDe())
.ersrRegistDe(res.getErsrRegistDe())
.ersrRegistSeCode(res.getErsrRegistSeCode())
.ersrRegistSeNm(res.getErsrRegistSeNm())
.mrtgcnt(res.getMrtgcnt())
.vhclecnt(res.getVhclecnt())
.stmdcnt(res.getStmdcnt())
.adres1(res.getAdres1())
.adresNm1(res.getAdresNm1())
.adres(res.getAdres())
.adresNm(res.getAdresNm())
.indvdlBsnmAt(res.getIndvdlBsnmAt())
.telno(res.getTelno())
.mberNm(res.getMberNm())
.mberSeCode(res.getMberSeCode())
.mberSeNo(res.getMberSeNo())
.taxxmptTrgterSeCode(res.getTaxxmptTrgterSeCode())
.taxxmptTrgterSeCodeNm(res.getTaxxmptTrgterSeCodeNm())
.cntMatter(res.getCntMatter())
.emdNm(res.getEmdNm())
.prvntccnt(res.getPrvntccnt())
.xportFlflAtSttemntDe(res.getXportFlflAtSttemntDe())
.partnRqrcno(res.getPartnRqrcno())
.build();
}
// PK
private String carLedgerFrmbkId;
// 요청(헤더/본문) 정보
private String infoSysId;
private String infoSysIp;
private String sigunguCode;
private String cntcInfoCode;
private String chargerId;
private String chargerIp;
private String chargerNm;
// 요청 본문
private String dmndVhrno;
private String dmndOnesInformationOpen;
private String dmndCpttrNm;
private String dmndCpttrIhidnum;
private String dmndCpttrLegaldongCode;
private String dmndRouteSeCode;
private String dmndDetailExpression;
private String dmndInqireSeCode;
// 응답 요약 정보
private String cntcResultCode;
private String cntcResultDtls;
// 응답 본문(마스터)
private String ledgerGroupNo;
private String ledgerIndvdlzNo;
private String vhmno;
private String vhrno;
private String vin;
private String vhctyAsortCode;
private String vhctyAsortNm;
private String cnm;
private String colorCode;
private String colorNm;
private String nmplStndrdCode;
private String nmplStndrdNm;
private String prposSeCode;
private String prposSeNm;
private String mtrsFomNm;
private String fomNm;
private String acqsAmount;
private String registDetailCode;
private String registDetailNm;
private String frstRegistDe;
private String caagEndde;
private String prye;
private String spmnno1;
private String spmnno2;
private String yblMd;
private String trvlDstnc;
private String insptValidPdBgnde;
private String insptValidPdEndde;
private String chckValidPdBgnde;
private String chckValidPdEndde;
private String registReqstSeNm;
private String frstRegistRqrcno;
private String nmplCsdyRemnrDe;
private String nmplCsdyAt;
private String bssUsePd;
private String octhtErsrPrvntcNticeDe;
private String ersrRegistDe;
private String ersrRegistSeCode;
private String ersrRegistSeNm;
private String mrtgcnt;
private String vhclecnt;
private String stmdcnt;
private String adres1;
private String adresNm1;
private String adres;
private String adresNm;
private String indvdlBsnmAt;
private String telno;
private String mberNm;
private String mberSeCode;
private String mberSeNo;
private String taxxmptTrgterSeCode;
private String taxxmptTrgterSeCodeNm;
private String cntMatter;
private String emdNm;
private String prvntccnt;
private String xportFlflAtSttemntDe;
private String partnRqrcno;
private String frstTrnsfrDe;
private String processImprtyResnCode;
private String processImprtyResnDtls;
// 감사
private String rgtr;
}

@ -0,0 +1,56 @@
package com.vmis.interfaceapp.service;
import com.vmis.interfaceapp.mapper.CarBassMatterInqireMapper;
import com.vmis.interfaceapp.model.basic.CarBassMatterInqireVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* .
*
* <p> (REQUIRES_NEW) ,
* .</p>
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CarBassMatterInqireLogService {
private final CarBassMatterInqireMapper carBassMatterInqireMapper;
/**
* API . (REQUIRES_NEW)
* @param request
* @return ID
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public String createInitialRequestNewTx(CarBassMatterInqireVO request) {
String generatedId = carBassMatterInqireMapper.selectNextCarBassMatterInqireId();
request.setCarBassMatterInqire(generatedId);
int result = carBassMatterInqireMapper.insertCarBassMatterInqire(request);
if (result != 1) {
throw new RuntimeException("자동차 기본 사항 조회 정보 등록 실패");
}
log.info("[BASIC-REQ-LOG] 요청 정보 저장 완료(별도TX) - ID: {}, 차량번호: {}", generatedId, request.getDmndVhrno());
return generatedId;
}
/**
* / . (REQUIRES_NEW)
* @param response
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateResponseNewTx(CarBassMatterInqireVO response) {
if (response.getCarBassMatterInqire() == null) {
throw new IllegalArgumentException("자동차 기본 사항 조회 ID는 필수입니다.");
}
int result = carBassMatterInqireMapper.updateCarBassMatterInqire(response);
if (result != 1) {
throw new RuntimeException("자동차 기본 사항 조회 정보 업데이트 실패 - ID: " + response.getCarBassMatterInqire());
}
log.info("[BASIC-RES-LOG] 응답/에러 정보 저장 완료(별도TX) - ID: {}, 결과코드: {}", response.getCarBassMatterInqire(), response.getCntcResultCode());
}
}

@ -1,9 +1,14 @@
package com.vmis.interfaceapp.service;
import com.vmis.interfaceapp.mapper.CarBassMatterInqireMapper;
import com.vmis.interfaceapp.client.GovernmentApi;
import com.vmis.interfaceapp.util.ExceptionDetailUtil;
import com.vmis.interfaceapp.model.basic.BasicRequest;
import com.vmis.interfaceapp.model.basic.BasicResponse;
import com.vmis.interfaceapp.model.basic.CarBassMatterInqireVO;
import com.vmis.interfaceapp.model.common.Envelope;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -21,106 +26,61 @@ import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
public class CarBassMatterInqireService {
private final CarBassMatterInqireMapper carBassMatterInqireMapper;
private final GovernmentApi governmentApi;
private final RequestEnricher enricher;
private final CarBassMatterInqireLogService logService;
/**
* API .
*
* <p>퀀 ID .
* , .</p>
*
* <p> :</p>
* <pre>
* {@code
* CarBassMatterInqire request = CarBassMatterInqire.builder()
* .infoSysId("41-345")
* .infoSysIp("105.19.10.135")
* .sigunguCode("41460")
* .cntcInfoCode("AC1_FD11_01")
* .dmndVhrno("12가3456")
* .rgtr("SYSTEM")
* .build();
*
* String generatedId = service.createInitialRequest(request);
* log.info("생성된 ID: {}", generatedId);
* }
* </pre>
*
* @param request (ID )
* @return ID (CBMI000000000001 )
* @throws RuntimeException
*/
@Transactional
public String createInitialRequest(CarBassMatterInqireVO request) {
// 시퀀스로 새로운 ID 생성
String generatedId = carBassMatterInqireMapper.selectNextCarBassMatterInqireId();
log.debug("생성된 자동차 기본 사항 조회 ID: {}", generatedId);
// 생성된 ID 설정
request.setCarBassMatterInqire(generatedId);
// INSERT
int result = carBassMatterInqireMapper.insertCarBassMatterInqire(request);
if (result != 1) {
throw new RuntimeException("자동차 기본 사항 조회 정보 등록 실패");
}
log.info("자동차 기본 사항 조회 정보 등록 완료 - ID: {}, 차량번호: {}, 차대번호: {}",
generatedId, request.getDmndVhrno(), request.getDmndVin());
return generatedId;
}
/**
* API .
*
* <p> .
* null , .</p>
*
* <p> :</p>
* <pre>
* {@code
* CarBassMatterInqire response = CarBassMatterInqire.builder()
* .carBassMatterInqire("CBMI000000000001")
* .cntcResultCode("00")
* .cntcResultDtls("성공")
* .vhclno("12가3456")
* .vin("KMHXX00XXXX000000")
* .cnm("소나타")
* // ... 기타 응답 필드
* .build();
*
* service.updateResponse(response);
* }
* </pre>
*
* @param response (carBassMatterInqire )
* @throws RuntimeException ( )
* : -> -> -> .
*/
@Transactional
public void updateResponse(CarBassMatterInqireVO response) {
if (response.getCarBassMatterInqire() == null) {
throw new IllegalArgumentException("자동차 기본 사항 조회 ID는 필수입니다.");
}
public ResponseEntity<Envelope<BasicResponse>> basic(Envelope<BasicRequest> envelope) {
// 1) 요청 보강
enricher.enrichBasic(envelope);
int result = carBassMatterInqireMapper.updateCarBassMatterInqire(response);
if (result != 1) {
throw new RuntimeException("자동차 기본 사항 조회 정보 업데이트 실패 - ID: " + response.getCarBassMatterInqire());
}
String generatedId = null;
try {
// 2) 최초 요청 로그 저장 (첫 번째 데이터 기준)
if (envelope.getData() != null && !envelope.getData().isEmpty()) {
BasicRequest req = envelope.getData().get(0);
CarBassMatterInqireVO logEntity = CarBassMatterInqireVO.fromRequest(req);
generatedId = logService.createInitialRequestNewTx(logEntity);
}
log.info("자동차 기본 사항 조회 정보 업데이트 완료 - ID: {}, 결과코드: {}, 차량번호: {}",
response.getCarBassMatterInqire(), response.getCntcResultCode(), response.getVhclno());
}
// 3) 외부 API 호출
ResponseEntity<Envelope<BasicResponse>> response = governmentApi.callBasic(envelope);
/**
* ID .
*
* @param carBassMatterInqire ID
* @return ( null)
*/
@Transactional(readOnly = true)
public CarBassMatterInqireVO getById(String carBassMatterInqire) {
return carBassMatterInqireMapper.selectCarBassMatterInqireById(carBassMatterInqire);
// 4) 응답 로그 업데이트
// 원본 소스, 정상적인 호출, 리턴(에러 리턴포함) 일 경우에만 에러 로그 남김
if (generatedId != null && response.getBody() != null) {
CarBassMatterInqireVO update = CarBassMatterInqireVO.fromResponse(generatedId, response.getBody());
if (update != null) {
logService.updateResponseNewTx(update);
}
}
return response;
} catch (Exception e) {
// 5) 오류 로그 업데이트
if (generatedId != null) {
try {
String detail = ExceptionDetailUtil.buildForLog(e);
CarBassMatterInqireVO errorLog = CarBassMatterInqireVO.builder()
.carBassMatterInqire(generatedId) // 자동차기본사항조회 ID (PK)
.cntcResultCode("99") // 연계결과코드 (99: 에러)
.cntcResultDtls(detail) // 연계결과상세 (에러 메시지)
.build();
logService.updateResponseNewTx(errorLog);
log.error("[BASIC-ERR-LOG] API 호출 에러 정보 저장 완료(별도TX) - ID: {}, detail: {}", generatedId, detail, e);
} catch (Exception ignore) {
log.error("[BASIC-ERR-LOG] 에러 로그 저장 실패 - ID: {}", generatedId, ignore);
}
}
throw e;
}
}
}

@ -0,0 +1,61 @@
package com.vmis.interfaceapp.service;
import com.vmis.interfaceapp.mapper.CarLedgerFrmbkMapper;
import com.vmis.interfaceapp.model.ledger.CarLedgerFrmbkDtlVO;
import com.vmis.interfaceapp.model.ledger.CarLedgerFrmbkVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* () .
* - (write) (REQUIRES_NEW) .
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CarLedgerFrmbkLogService {
private final CarLedgerFrmbkMapper mapper;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public String createInitialRequestNewTx(CarLedgerFrmbkVO request) {
String id = mapper.selectNextCarLedgerFrmbkId();
request.setCarLedgerFrmbkId(id);
int result = mapper.insertCarLedgerFrmbk(request);
if (result != 1) {
throw new RuntimeException("자동차 등록 원부(갑) 최초요청 등록 실패");
}
log.info("[LEDGER-REQ-LOG] 최초 요청 저장(별도TX) - ID: {}, 차량번호: {}", id, request.getDmndVhrno());
return id;
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateResponseNewTx(CarLedgerFrmbkVO response) {
if (response.getCarLedgerFrmbkId() == null) {
throw new IllegalArgumentException("자동차 등록 원부(갑) ID는 필수입니다.");
}
int updated = mapper.updateCarLedgerFrmbk(response);
if (updated != 1) {
throw new RuntimeException("자동차 등록 원부(갑) 정보 업데이트 실패 - ID: " + response.getCarLedgerFrmbkId());
}
log.info("[LEDGER-RES-LOG] 마스터 응답 업데이트(별도TX) - ID: {}, 결과코드: {}",
response.getCarLedgerFrmbkId(), response.getCntcResultCode());
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveDetailsNewTx(String masterId, List<CarLedgerFrmbkDtlVO> details) {
if (details == null || details.isEmpty()) return;
for (CarLedgerFrmbkDtlVO dtl : details) {
String dtlId = mapper.selectNextCarLedgerFrmbkDtlId();
dtl.setCarLedgerFrmbkDtlId(dtlId);
dtl.setCarLedgerFrmbkId(masterId);
mapper.insertCarLedgerFrmbkDtl(dtl);
}
log.info("[LEDGER-RES-LOG] 상세 {}건 저장(별도TX) - ID: {}", details.size(), masterId);
}
}

@ -0,0 +1,84 @@
package com.vmis.interfaceapp.service;
import com.vmis.interfaceapp.client.GovernmentApi;
import com.vmis.interfaceapp.model.common.Envelope;
import com.vmis.interfaceapp.model.ledger.CarLedgerFrmbkDtlVO;
import com.vmis.interfaceapp.model.ledger.CarLedgerFrmbkVO;
import com.vmis.interfaceapp.model.ledger.LedgerRequest;
import com.vmis.interfaceapp.model.ledger.LedgerResponse;
import com.vmis.interfaceapp.util.ExceptionDetailUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* () ()
* - , API ,
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CarLedgerFrmbkService {
private final GovernmentApi governmentApi;
private final RequestEnricher enricher;
private final CarLedgerFrmbkLogService logService;
/**
* () : -> (TX) -> -> (/, TX) -> (TX).
*/
@Transactional
public ResponseEntity<Envelope<LedgerResponse>> ledger(Envelope<LedgerRequest> envelope) {
// 1) 요청 보강
enricher.enrichLedger(envelope);
String generatedId = null;
try {
// 2) 최초 요청 로그 저장 (첫 번째 데이터 기준)
if (envelope.getData() != null && !envelope.getData().isEmpty()) {
LedgerRequest req = envelope.getData().get(0);
CarLedgerFrmbkVO init = CarLedgerFrmbkVO.fromRequest(req);
generatedId = logService.createInitialRequestNewTx(init);
}
// 3) 외부 API 호출
ResponseEntity<Envelope<LedgerResponse>> response = governmentApi.callLedger(envelope);
// 4) 응답 로그 업데이트 (마스터 + 상세)
if (generatedId != null && response.getBody() != null &&
response.getBody().getData() != null && !response.getBody().getData().isEmpty()) {
LedgerResponse body = response.getBody().getData().get(0);
CarLedgerFrmbkVO masterUpdate = CarLedgerFrmbkVO.fromResponseMaster(generatedId, body);
logService.updateResponseNewTx(masterUpdate);
List<CarLedgerFrmbkDtlVO> details = CarLedgerFrmbkDtlVO.listFromResponse(body, generatedId);
if (details != null && !details.isEmpty()) {
logService.saveDetailsNewTx(generatedId, details);
}
}
return response;
} catch (Exception e) {
// 5) 오류 로그 업데이트
if (generatedId != null) {
try {
String detail = ExceptionDetailUtil.buildForLog(e);
CarLedgerFrmbkVO errorLog = CarLedgerFrmbkVO.builder()
.carLedgerFrmbkId(generatedId)
.cntcResultCode("99")
.cntcResultDtls(detail)
.build();
logService.updateResponseNewTx(errorLog);
log.error("[LEDGER-ERR-LOG] API 호출 에러 정보 저장 완료(별도TX) - ID: {}, detail: {}", generatedId, detail, e);
} catch (Exception ignore) {
log.error("[LEDGER-ERR-LOG] 에러 로그 저장 실패 - ID: {}", generatedId, ignore);
}
}
throw e;
}
}
}

@ -1,228 +0,0 @@
package com.vmis.interfaceapp.service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.vmis.interfaceapp.client.GovernmentApi;
import com.vmis.interfaceapp.model.basic.BasicRequest;
import com.vmis.interfaceapp.model.basic.BasicResponse;
import com.vmis.interfaceapp.model.basic.CarBassMatterInqireVO;
import com.vmis.interfaceapp.model.common.Envelope;
import com.vmis.interfaceapp.model.ledger.LedgerRequest;
import com.vmis.interfaceapp.model.ledger.LedgerResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* : - .
* - (RequestEnricher)
* - / DB (CarBassMatterInqire)
* - API (GovernmentApi)
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class VehicleInterfaceService {
private final GovernmentApi governmentApi;
private final RequestEnricher enricher;
private final CarBassMatterInqireService carBassMatterInqireService;
/**
* : -> -> -> .
*/
@Transactional
public ResponseEntity<Envelope<BasicResponse>> basic(Envelope<BasicRequest> envelope) {
// 1) 요청 보강
enricher.enrichBasic(envelope);
String generatedId = null;
try {
// 2) 최초 요청 로그 저장 (첫 번째 데이터 기준)
if (envelope.getData() != null && !envelope.getData().isEmpty()) {
BasicRequest req = envelope.getData().get(0);
CarBassMatterInqireVO logEntity = mapInitialLog(req);
generatedId = carBassMatterInqireService.createInitialRequest(logEntity);
log.info("[BASIC-REQ-LOG] 요청 정보 저장 완료 - ID: {}, 차량번호: {}", generatedId, req.getVhrno());
}
// 3) 외부 API 호출
ResponseEntity<Envelope<BasicResponse>> response = governmentApi.callBasic(envelope);
// 4) 응답 로그 업데이트
// 원본 소스, 정상적인 호출, 리턴(에러 리턴포함) 일 경우에만 에러 로그 남김
if (generatedId != null && response.getBody() != null) {
CarBassMatterInqireVO update = mapResponseLog(generatedId, response.getBody());
if (update != null) {
carBassMatterInqireService.updateResponse(update);
log.info("[BASIC-RES-LOG] 응답 정보 저장 완료 - ID: {}", generatedId);
}
}
return response;
} catch (Exception e) {
// 5) 오류 로그 업데이트
if (generatedId != null) {
try {
String detail = buildExceptionDetail(e);
CarBassMatterInqireVO errorLog = CarBassMatterInqireVO.builder()
.carBassMatterInqire(generatedId)
.cntcResultCode("99")
.cntcResultDtls(detail)
.build();
carBassMatterInqireService.updateResponse(errorLog);
log.error("[BASIC-ERR-LOG] API 호출 에러 정보 저장 완료 - ID: {}, detail: {}", generatedId, detail, e);
} catch (Exception ignore) {
log.error("[BASIC-ERR-LOG] 에러 로그 저장 실패 - ID: {}", generatedId, ignore);
}
}
throw e;
}
}
/**
* () : -> . ( )
*/
public ResponseEntity<Envelope<LedgerResponse>> ledger(Envelope<LedgerRequest> envelope) {
enricher.enrichLedger(envelope);
return governmentApi.callLedger(envelope);
}
private CarBassMatterInqireVO mapInitialLog(BasicRequest request) {
return CarBassMatterInqireVO.builder()
.infoSysId(request.getInfoSysId())
.infoSysIp(request.getInfoSysIp())
.sigunguCode(request.getSigunguCode())
.cntcInfoCode(request.getCntcInfoCode())
.chargerId(request.getChargerId())
.chargerIp(request.getChargerIp())
.chargerNm(request.getChargerNm())
.dmndLevyStdde(request.getLevyStdde())
.dmndInqireSeCode(request.getInqireSeCode())
.dmndVhrno(request.getVhrno())
.dmndVin(request.getVin())
.rgtr("SYSTEM")
.build();
}
private CarBassMatterInqireVO mapResponseLog(String id, Envelope<BasicResponse> envelope) {
if (envelope.getData() == null || envelope.getData().isEmpty()) return null;
BasicResponse response = envelope.getData().get(0);
CarBassMatterInqireVO.CarBassMatterInqireVOBuilder builder = CarBassMatterInqireVO.builder()
.carBassMatterInqire(id)
.cntcResultCode(response.getCntcResultCode())
.cntcResultDtls(response.getCntcResultDtls());
if (response.getRecord() != null && !response.getRecord().isEmpty()) {
BasicResponse.Record record = response.getRecord().get(0);
mapRecordToEntity(builder, record);
}
return builder.build();
}
private void mapRecordToEntity(CarBassMatterInqireVO.CarBassMatterInqireVOBuilder builder, BasicResponse.Record record) {
builder
.prye(record.getPrye())
.registDe(record.getRegistDe())
.ersrRegistSeCode(record.getErsrRegistSeCode())
.ersrRegistSeNm(record.getErsrRegistSeNm())
.ersrRegistDe(record.getErsrRegistDe())
.registDetailCode(record.getRegistDetailCode())
.dsplvl(record.getDsplvl())
.useStrnghldLegaldongCode(record.getUseStrnghldLegaldongCode())
.useStrnghldAdstrdCode(record.getUseStrnghldAdstrdCode())
.useStrnghldMntn(record.getUseStrnghldMntn())
.useStrnghldLnbr(record.getUseStrnghldLnbr())
.useStrnghldHo(record.getUseStrnghldHo())
.useStrnghldAdresNm(record.getUseStrnghldAdresNm())
.useStrnghldRoadNmCode(record.getUseStrnghldRoadNmCode())
.usgsrhldUndgrndBuldSeCode(record.getUsgsrhldUndgrndBuldSeCode())
.useStrnghldBuldMainNo(record.getUseStrnghldBuldMainNo())
.useStrnghldBuldSubNo(record.getUseStrnghldBuldSubNo())
.usgsrhldAdresFull(record.getUsgsrhldAdresFull())
.mberSeCode(record.getMberSeCode())
.mberSeNo(record.getMberSeNo())
.mberNm(record.getMberNm())
.telno(record.getTelno())
.ownerLegaldongCode(record.getOwnerLegaldongCode())
.ownerAdstrdCode(record.getOwnerAdstrdCode())
.ownerMntn(record.getOwnerMntn())
.ownerLnbr(record.getOwnerLnbr())
.ownerHo(record.getOwnerHo())
.ownerAdresNm(record.getOwnerAdresNm())
.ownerRoadNmCode(record.getOwnerRoadNmCode())
.ownerUndgrndBuldSeCode(record.getOwnerUndgrndBuldSeCode())
.ownerBuldMainNo(record.getOwnerBuldMainNo())
.ownerBuldSubNo(record.getOwnerBuldSubNo())
.ownrWholaddr(record.getOwnerAdresFull())
.aftrVhrno(record.getAftrVhrno())
.useFuelCode(record.getUseFuelCode())
.prposSeCode(record.getPrposSeCode())
.mtrsFomNm(record.getMtrsFomNm())
.frntVhrno(record.getFrntVhrno())
.vhclno(record.getVhrno())
.vin(record.getVin())
.cnm(record.getCnm())
.vhcleTotWt(record.getVhcleTotWt())
.caagEndde(record.getCaagEndde())
.changeDe(record.getChangeDe())
.vhctyAsortCode(record.getVhctyAsortCode())
.vhctyTyCode(record.getVhctyTyCode())
.vhctySeCode(record.getVhctySeCode())
.mxmmLdg(record.getMxmmLdg())
.vhctyAsortNm(record.getVhctyAsortNm())
.vhctyTyNm(record.getVhctyTyNm())
.vhctySeNm(record.getVhctySeNm())
.frstRegistDe(record.getFrstRegistDe())
.fomNm(record.getFomNm())
.acqsDe(record.getAcqsDe())
.acqsEndDe(record.getAcqsEndDe())
.yblMd(record.getYblMd())
.transrRegistDe(record.getTransrRegistDe())
.spcfRegistSttusCode(record.getSpcfRegistSttusCode())
.colorNm(record.getColorNm())
.mrtgCo(record.getMrtgCo())
.seizrCo(record.getSeizrCo())
.stmdCo(record.getStmdCo())
.nmplCsdyAt(record.getNmplCsdyAt())
.nmplCsdyRemnrDe(record.getNmplCsdyRemnrDe())
.originSeCode(record.getOriginSeCode())
.nmplStndrdCode(record.getNmplStndrdCode())
.acqsAmount(record.getAcqsAmount())
.insptValidPdBgnde(record.getInsptValidPdBgnde())
.insptValidPdEndde(record.getInsptValidPdEndde())
.useStrnghldGrcCode(record.getUseStrnghldGrcCode())
.tkcarPscapCo(record.getTkcarPscapCo())
.spmnno(record.getSpmnno())
.trvlDstnc(record.getTrvlDstnc())
.frstRegistRqrcno(record.getFrstRegistRqrcno())
.vlntErsrPrvntcNticeDe(record.getVlntErsrPrvntcNticeDe())
.registInsttNm(record.getRegistInsttNm())
.processImprtyResnCode(record.getProcessImprtyResnCode())
.processImprtyResnDtls(record.getProcessImprtyResnDtls())
.cbdLt(record.getCbdLt())
.cbdBt(record.getCbdBt())
.cbdHg(record.getCbdHg())
.frstMxmmLdg(record.getFrstMxmmLdg())
.fuelCnsmpRt(record.getFuelCnsmpRt())
.elctyCmpndFuelCnsmpRt(record.getElctyCmpndFuelCnsmpRt());
}
private String buildExceptionDetail(Throwable t) {
if (t == null) return "오류: unknown";
Throwable root = t;
int guard = 0;
while (root.getCause() != null && root.getCause() != root && guard++ < 20) {
root = root.getCause();
}
String className = root.getClass().getName();
String message = root.getMessage();
String detail = (message != null && !message.isEmpty()) ? (className + ": " + message) : root.toString();
// DB 컬럼(CNTC_RESULT_DTLS) 길이: 200
if (detail.length() > 200) {
detail = detail.substring(0, 200);
}
return detail;
}
}

@ -0,0 +1,29 @@
package com.vmis.interfaceapp.util;
/**
* Common helper to extract root-cause message and truncate to DB column limit (default 4000 chars).
*/
public final class ExceptionDetailUtil {
private ExceptionDetailUtil() {}
public static String buildForLog(Throwable t) {
return buildForLog(t, 4000);
}
public static String buildForLog(Throwable t, int maxLen) {
if (t == null) return "오류: unknown";
Throwable root = t;
int guard = 0;
while (root.getCause() != null && root.getCause() != root && guard++ < 20) {
root = root.getCause();
}
String className = root.getClass().getName();
String message = root.getMessage();
String detail = (message != null && !message.isEmpty()) ? (className + ": " + message) : root.toString();
if (detail != null && detail.length() > maxLen) {
detail = detail.substring(0, maxLen);
}
return detail;
}
}

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.vmis.interfaceapp.mapper.CarLedgerFrmbkMapper">
<!-- 시퀀스로 새로운 마스터/상세 ID 생성 -->
<select id="selectNextCarLedgerFrmbkId" resultType="String">
SELECT CONCAT('CLFB', LPAD(NEXTVAL(seq_car_ledger_frmbk), 16, '0')) AS id
</select>
<select id="selectNextCarLedgerFrmbkDtlId" resultType="String">
SELECT CONCAT('CLFD', LPAD(NEXTVAL(seq_car_ledger_frmbk_dtl), 16, '0')) AS id
</select>
<!-- 최초 요청 정보 INSERT (마스터) -->
<insert id="insertCarLedgerFrmbk" parameterType="CarLedgerFrmbkVO">
INSERT INTO tb_car_ledger_frmbk (
CAR_LEDGER_FRMBK_ID,
INFO_SYS_ID,
INFO_SYS_IP,
SIGUNGU_CODE,
CNTC_INFO_CODE,
CHARGER_ID,
CHARGER_IP,
CHARGER_NM,
DMND_VHRNO,
DMND_ONES_INFORMATION_OPEN,
DMND_CPTTR_NM,
DMND_CPTTR_IHIDNUM,
DMND_CPTTR_LEGALDONG_CODE,
DMND_ROUTE_SE_CODE,
DMND_DETAIL_EXPRESSION,
DMND_INQIRE_SE_CODE,
REG_DT,
RGTR
) VALUES (
#{carLedgerFrmbkId},
#{infoSysId},
#{infoSysIp},
#{sigunguCode},
#{cntcInfoCode},
#{chargerId},
#{chargerIp},
#{chargerNm},
#{dmndVhrno},
#{dmndOnesInformationOpen},
#{dmndCpttrNm},
#{dmndCpttrIhidnum},
#{dmndCpttrLegaldongCode},
#{dmndRouteSeCode},
#{dmndDetailExpression},
#{dmndInqireSeCode},
NOW(),
#{rgtr}
)
</insert>
<!-- 응답 결과 UPDATE (마스터) -->
<update id="updateCarLedgerFrmbk" parameterType="CarLedgerFrmbkVO">
UPDATE tb_car_ledger_frmbk
<set>
<if test="cntcResultCode != null">CNTC_RESULT_CODE = #{cntcResultCode},</if>
<if test="cntcResultDtls != null">CNTC_RESULT_DTLS = #{cntcResultDtls},</if>
<if test="ledgerGroupNo != null">LEDGER_GROUP_NO = #{ledgerGroupNo},</if>
<if test="ledgerIndvdlzNo != null">LEDGER_INDVDLZ_NO = #{ledgerIndvdlzNo},</if>
<if test="vhmno != null">VHMNO = #{vhmno},</if>
<if test="vhrno != null">VHRNO = #{vhrno},</if>
<if test="vin != null">VIN = #{vin},</if>
<if test="vhctyAsortCode != null">VHCTY_ASORT_CODE = #{vhctyAsortCode},</if>
<if test="vhctyAsortNm != null">VHCTY_ASORT_NM = #{vhctyAsortNm},</if>
<if test="cnm != null">CNM = #{cnm},</if>
<if test="colorCode != null">COLOR_CODE = #{colorCode},</if>
<if test="colorNm != null">COLOR_NM = #{colorNm},</if>
<if test="nmplStndrdCode != null">NMPL_STNDRD_CODE = #{nmplStndrdCode},</if>
<if test="nmplStndrdNm != null">NMPL_STNDRD_NM = #{nmplStndrdNm},</if>
<if test="prposSeCode != null">PRPOS_SE_CODE = #{prposSeCode},</if>
<if test="prposSeNm != null">PRPOS_SE_NM = #{prposSeNm},</if>
<if test="mtrsFomNm != null">MTRS_FOM_NM = #{mtrsFomNm},</if>
<if test="fomNm != null">FOM_NM = #{fomNm},</if>
<if test="acqsAmount != null">ACQS_AMOUNT = #{acqsAmount},</if>
<if test="registDetailCode != null">REGIST_DETAIL_CODE = #{registDetailCode},</if>
<if test="registDetailNm != null">REGIST_DETAIL_NM = #{registDetailNm},</if>
<if test="frstRegistDe != null">FRST_REGIST_DE = #{frstRegistDe},</if>
<if test="caagEndde != null">CAAG_ENDDE = #{caagEndde},</if>
<if test="prye != null">PRYE = #{prye},</if>
<if test="spmnno1 != null">SPMNNO1 = #{spmnno1},</if>
<if test="spmnno2 != null">SPMNNO2 = #{spmnno2},</if>
<if test="yblMd != null">YBL_MD = #{yblMd},</if>
<if test="trvlDstnc != null">TRVL_DSTNC = #{trvlDstnc},</if>
<if test="insptValidPdBgnde != null">INSPT_VALID_PD_BGNDE = #{insptValidPdBgnde},</if>
<if test="insptValidPdEndde != null">INSPT_VALID_PD_ENDDE = #{insptValidPdEndde},</if>
<if test="chckValidPdBgnde != null">CHCK_VALID_PD_BGNDE = #{chckValidPdBgnde},</if>
<if test="chckValidPdEndde != null">CHCK_VALID_PD_ENDDE = #{chckValidPdEndde},</if>
<if test="registReqstSeNm != null">REGIST_REQST_SE_NM = #{registReqstSeNm},</if>
<if test="frstRegistRqrcno != null">FRST_REGIST_RQRCNO = #{frstRegistRqrcno},</if>
<if test="nmplCsdyRemnrDe != null">NMPL_CSDY_REMNR_DE = #{nmplCsdyRemnrDe},</if>
<if test="nmplCsdyAt != null">NMPL_CSDY_AT = #{nmplCsdyAt},</if>
<if test="bssUsePd != null">BSS_USE_PD = #{bssUsePd},</if>
<if test="octhtErsrPrvntcNticeDe != null">OCTHT_ERSR_PRVNTC_NTICE_DE = #{octhtErsrPrvntcNticeDe},</if>
<if test="ersrRegistDe != null">ERSR_REGIST_DE = #{ersrRegistDe},</if>
<if test="ersrRegistSeCode != null">ERSR_REGIST_SE_CODE = #{ersrRegistSeCode},</if>
<if test="ersrRegistSeNm != null">ERSR_REGIST_SE_NM = #{ersrRegistSeNm},</if>
<if test="mrtgcnt != null">MRTGCNT = #{mrtgcnt},</if>
<if test="vhclecnt != null">VHCLECNT = #{vhclecnt},</if>
<if test="stmdcnt != null">STMDCNT = #{stmdcnt},</if>
<if test="adres1 != null">ADRES1 = #{adres1},</if>
<if test="adresNm1 != null">ADRES_NM1 = #{adresNm1},</if>
<if test="adres != null">ADRES = #{adres},</if>
<if test="adresNm != null">ADRES_NM = #{adresNm},</if>
<if test="indvdlBsnmAt != null">INDVDL_BSNM_AT = #{indvdlBsnmAt},</if>
<if test="telno != null">TELNO = #{telno},</if>
<if test="mberNm != null">MBER_NM = #{mberNm},</if>
<if test="mberSeCode != null">MBER_SE_CODE = #{mberSeCode},</if>
<if test="mberSeNo != null">MBER_SE_NO = #{mberSeNo},</if>
<if test="taxxmptTrgterSeCode != null">TAXXMPT_TRGTER_SE_CODE = #{taxxmptTrgterSeCode},</if>
<if test="taxxmptTrgterSeCodeNm != null">TAXXMPT_TRGTER_SE_CODE_NM = #{taxxmptTrgterSeCodeNm},</if>
<if test="cntMatter != null">CNT_MATTER = #{cntMatter},</if>
<if test="emdNm != null">EMD_NM = #{emdNm},</if>
<if test="prvntccnt != null">PRVNTCCNT = #{prvntccnt},</if>
<if test="xportFlflAtSttemntDe != null">XPORT_FLFL_AT_STTEMNT_DE = #{xportFlflAtSttemntDe},</if>
<if test="partnRqrcno != null">PARTN_RQRCNO = #{partnRqrcno},</if>
<if test="frstTrnsfrDe != null">FRST_TRNSFR_DE = #{frstTrnsfrDe},</if>
<if test="processImprtyResnCode != null">PROCESS_IMPRTY_RESN_CODE = #{processImprtyResnCode},</if>
<if test="processImprtyResnDtls != null">PROCESS_IMPRTY_RESN_DTLS = #{processImprtyResnDtls},</if>
</set>
WHERE CAR_LEDGER_FRMBK_ID = #{carLedgerFrmbkId}
</update>
<!-- 상세 INSERT -->
<insert id="insertCarLedgerFrmbkDtl" parameterType="CarLedgerFrmbkDtlVO">
INSERT INTO tb_car_ledger_frmbk_dtl (
CAR_LEDGER_FRMBK_DTL_ID,
CAR_LEDGER_FRMBK_ID,
MAINCHK,
CHANGE_JOB_SE_CODE,
MAINNO,
SUBNO,
DTLS,
RQRCNO,
VHMNO,
LEDGER_GROUP_NO,
LEDGER_INDVDLZ_NO,
GUBUN_NM,
CHANGE_DE,
DETAIL_SN,
FLAG,
REG_DT,
RGTR
) VALUES (
#{carLedgerFrmbkDtlId},
#{carLedgerFrmbkId},
#{mainchk},
#{changeJobSeCode},
#{mainno},
#{subno},
#{dtls},
#{rqrcno},
#{vhmno},
#{ledgerGroupNo},
#{ledgerIndvdlzNo},
#{gubunNm},
#{changeDe},
#{detailSn},
#{flag},
NOW(),
#{rgtr}
)
</insert>
<!-- ID로 조회 (선택) -->
<select id="selectCarLedgerFrmbkById" parameterType="String" resultType="CarLedgerFrmbkVO">
SELECT *
FROM tb_car_ledger_frmbk
WHERE CAR_LEDGER_FRMBK_ID = #{carLedgerFrmbkId}
</select>
</mapper>
Loading…
Cancel
Save