diff --git a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskMapper.java b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskMapper.java index 1dd1166..bc6f8d7 100644 --- a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskMapper.java +++ b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/mapper/CrdnImpltTaskMapper.java @@ -98,6 +98,36 @@ public interface CrdnImpltTaskMapper { */ List selectActrInfoList(CrdnImpltTaskVO vo); + /** + * 중요한 로직: OWNR_ID와 ACT_INFO_ID로 소유자정보ID(OWNR_INFO_ID)를 조회한다. + * @param ownrId 소유자 ID + * @param actInfoId 행위정보 ID + * @param crdnYr 단속 연도 + * @param crdnNo 단속 번호 + * @return 소유자정보 ID + */ + String selectOwnrInfoIdByOwnrIdAndActInfoId(@Param("ownrId") String ownrId, @Param("actInfoId") String actInfoId, @Param("crdnYr") String crdnYr, @Param("crdnNo") String crdnNo); + + /** + * 중요한 로직: OWNR_ID와 ACT_INFO_ID로 행위자정보ID(ACTR_INFO_ID)를 조회한다. + * @param ownrId 소유자 ID + * @param actInfoId 행위정보 ID + * @param crdnYr 단속 연도 + * @param crdnNo 단속 번호 + * @return 행위자정보 ID + */ + String selectActrInfoIdByOwnrIdAndActInfoId(@Param("ownrId") String ownrId, @Param("actInfoId") String actInfoId, @Param("crdnYr") String crdnYr, @Param("crdnNo") String crdnNo); + + // ==================== 이행정보 전용 행위 조회 메서드 ==================== + + /** + * 중요한 로직: 이행정보 등록/수정 시 단속건의 모든 행위 정보를 조회한다. (pstnInfoId 조건 없음) + * @param crdnYr 단속 연도 + * @param crdnNo 단속 번호 + * @return 행위 정보 목록 + */ + List selectActInfoListForImplt(@Param("crdnYr") String crdnYr, @Param("crdnNo") String crdnNo); + // ==================== 시퀀스 관련 메서드 ==================== /** diff --git a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskServiceImpl.java b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskServiceImpl.java index bf1b34b..9189050 100644 --- a/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskServiceImpl.java +++ b/src/main/java/go/kr/project/crdn/crndRegistAndView/main/service/impl/CrdnImpltTaskServiceImpl.java @@ -5,6 +5,7 @@ import egovframework.constant.TuiGridColorConstants; import egovframework.exception.MessageException; import egovframework.util.SessionUtil; import egovframework.util.StringUtil; +import go.kr.project.crdn.crndRegistAndView.crdnActInfo.model.CrdnActInfoVO; import go.kr.project.crdn.crndRegistAndView.main.mapper.CrdnImpltTaskMapper; import go.kr.project.crdn.crndRegistAndView.main.mapper.CrdnLevyPrvntcMapper; import go.kr.project.crdn.crndRegistAndView.main.mapper.CrdnRegistAndViewMapper; @@ -113,17 +114,63 @@ public class CrdnImpltTaskServiceImpl extends EgovAbstractServiceImpl implements // 이행정보 등록 int result = crdnImpltTaskMapper.insertImpltInfo(vo); - // 이행 대상자 정보 등록 + // 중요한 로직 주석: 단속건의 모든 행위를 조회하여 각 행위별로 이행 대상자 정보를 저장 if (vo.getImpltTrprInfoList() != null && !vo.getImpltTrprInfoList().isEmpty()) { - for (CrdnImpltTrprInfoVO trprInfo : vo.getImpltTrprInfoList()) { - String trprInfoId = crdnImpltTaskMapper.selectNextImpltTrprInfoId(); - trprInfo.setImpltTrprInfoId(trprInfoId); - trprInfo.setImpltInfoId(impltInfoId); - trprInfo.setSggCd(vo.getSggCd()); - trprInfo.setRgtr(SessionUtil.getUserId()); - trprInfo.setDelYn("N"); - - crdnImpltTaskMapper.insertImpltTrprInfo(trprInfo); + // 단속건의 모든 행위 정보 조회 (pstnInfoId 조건 없음) + List actInfoList = crdnImpltTaskMapper.selectActInfoListForImplt(vo.getCrdnYr(), vo.getCrdnNo()); + + if (actInfoList == null || actInfoList.isEmpty()) { + log.warn("행위 정보가 없습니다. 단속연도: {}, 단속번호: {}", vo.getCrdnYr(), vo.getCrdnNo()); + } else { + // 각 소유자/행위자에 대해 모든 행위별로 저장 + for (CrdnImpltTrprInfoVO trprInfo : vo.getImpltTrprInfoList()) { + for (CrdnActInfoVO actInfo : actInfoList) { + // 중요한 로직: OWNR_ID로 실제 OWNR_INFO_ID 또는 ACTR_INFO_ID 조회 + String actualInfoId = null; + if ("1".equals(trprInfo.getImpltTrprSeCd())) { + // 소유자인 경우 + actualInfoId = crdnImpltTaskMapper.selectOwnrInfoIdByOwnrIdAndActInfoId( + trprInfo.getOwnrActrInfoId(), actInfo.getActInfoId(), vo.getCrdnYr(), vo.getCrdnNo()); + } else if ("2".equals(trprInfo.getImpltTrprSeCd())) { + // 행위자인 경우 + actualInfoId = crdnImpltTaskMapper.selectActrInfoIdByOwnrIdAndActInfoId( + trprInfo.getOwnrActrInfoId(), actInfo.getActInfoId(), vo.getCrdnYr(), vo.getCrdnNo()); + } + + if (actualInfoId == null) { + log.warn("실제 ID를 찾을 수 없습니다. OWNR_ID: {}, ACT_INFO_ID: {}, 구분: {}", + trprInfo.getOwnrActrInfoId(), actInfo.getActInfoId(), trprInfo.getImpltTrprSeCd()); + continue; + } + + String trprInfoId = crdnImpltTaskMapper.selectNextImpltTrprInfoId(); + CrdnImpltTrprInfoVO newTrprInfo = new CrdnImpltTrprInfoVO(); + newTrprInfo.setImpltTrprInfoId(trprInfoId); + newTrprInfo.setImpltInfoId(impltInfoId); + newTrprInfo.setSggCd(vo.getSggCd()); + newTrprInfo.setRgtr(SessionUtil.getUserId()); + newTrprInfo.setDelYn("N"); + + // 실제 조회한 ID 설정 + newTrprInfo.setOwnrActrInfoId(actualInfoId); + newTrprInfo.setImpltTrprSeCd(trprInfo.getImpltTrprSeCd()); + newTrprInfo.setImpltTrprFlnm(trprInfo.getImpltTrprFlnm()); + newTrprInfo.setImpltTrprZip(trprInfo.getImpltTrprZip()); + newTrprInfo.setImpltTrprAddr(trprInfo.getImpltTrprAddr()); + newTrprInfo.setImpltTrprDaddr(trprInfo.getImpltTrprDaddr()); + + // 행위 정보 설정 + newTrprInfo.setActNo(String.valueOf(actInfo.getActNo())); + newTrprInfo.setActTypeCd(actInfo.getActTypeCd()); + newTrprInfo.setLotnoMno(trprInfo.getLotnoMno()); + newTrprInfo.setLotnoSno(trprInfo.getLotnoSno()); + + crdnImpltTaskMapper.insertImpltTrprInfo(newTrprInfo); + } + } + log.debug("이행 대상자 정보 등록 완료: 소유자/행위자 {}명 * 행위 {}건 = 총 {}건", + vo.getImpltTrprInfoList().size(), actInfoList.size(), + vo.getImpltTrprInfoList().size() * actInfoList.size()); } } @@ -165,17 +212,62 @@ public class CrdnImpltTaskServiceImpl extends EgovAbstractServiceImpl implements // 기존 이행 대상자 정보 삭제 crdnImpltTaskMapper.deleteImpltTrprInfoByImpltInfoId(vo.getImpltInfoId()); - // 새로운 이행 대상자 정보 등록 + // 중요한 로직 주석: 단속건의 모든 행위를 조회하여 각 행위별로 이행 대상자 정보를 저장 if (vo.getImpltTrprInfoList() != null && !vo.getImpltTrprInfoList().isEmpty()) { - for (CrdnImpltTrprInfoVO trprInfo : vo.getImpltTrprInfoList()) { - String trprInfoId = crdnImpltTaskMapper.selectNextImpltTrprInfoId(); - trprInfo.setImpltTrprInfoId(trprInfoId); - trprInfo.setImpltInfoId(vo.getImpltInfoId()); - trprInfo.setSggCd(vo.getSggCd()); - trprInfo.setRgtr(SessionUtil.getUserId()); - trprInfo.setDelYn("N"); - - crdnImpltTaskMapper.insertImpltTrprInfo(trprInfo); + // 단속건의 모든 행위 정보 조회 (pstnInfoId 조건 없음) + List actInfoList = crdnImpltTaskMapper.selectActInfoListForImplt(vo.getCrdnYr(), vo.getCrdnNo()); + + if (actInfoList == null || actInfoList.isEmpty()) { + throw new MessageException(String.format("행위 정보가 없습니다. 단속연도: %s, 단속번호: %s", vo.getCrdnYr(), vo.getCrdnNo())); + } else { + // 각 소유자/행위자에 대해 모든 행위별로 저장 + for (CrdnImpltTrprInfoVO trprInfo : vo.getImpltTrprInfoList()) { + for (CrdnActInfoVO actInfo : actInfoList) { + // 중요한 로직: OWNR_ID로 실제 OWNR_INFO_ID 또는 ACTR_INFO_ID 조회 + String actualInfoId = null; + if ("1".equals(trprInfo.getImpltTrprSeCd())) { + // 소유자인 경우 + actualInfoId = crdnImpltTaskMapper.selectOwnrInfoIdByOwnrIdAndActInfoId( + trprInfo.getOwnrActrInfoId(), actInfo.getActInfoId(), vo.getCrdnYr(), vo.getCrdnNo()); + } else if ("2".equals(trprInfo.getImpltTrprSeCd())) { + // 행위자인 경우 + actualInfoId = crdnImpltTaskMapper.selectActrInfoIdByOwnrIdAndActInfoId( + trprInfo.getOwnrActrInfoId(), actInfo.getActInfoId(), vo.getCrdnYr(), vo.getCrdnNo()); + } + + if (actualInfoId == null) { + throw new MessageException(String.format("실제 ID를 찾을 수 없습니다. OWNR_ID: %s, ACT_INFO_ID: %s, 구분: %s", + trprInfo.getOwnrActrInfoId(), actInfo.getActInfoId(), trprInfo.getImpltTrprSeCd())); + } + + String trprInfoId = crdnImpltTaskMapper.selectNextImpltTrprInfoId(); + CrdnImpltTrprInfoVO newTrprInfo = new CrdnImpltTrprInfoVO(); + newTrprInfo.setImpltTrprInfoId(trprInfoId); + newTrprInfo.setImpltInfoId(vo.getImpltInfoId()); + newTrprInfo.setSggCd(vo.getSggCd()); + newTrprInfo.setRgtr(SessionUtil.getUserId()); + newTrprInfo.setDelYn("N"); + + // 실제 조회한 ID 설정 + newTrprInfo.setOwnrActrInfoId(actualInfoId); + newTrprInfo.setImpltTrprSeCd(trprInfo.getImpltTrprSeCd()); + newTrprInfo.setImpltTrprFlnm(trprInfo.getImpltTrprFlnm()); + newTrprInfo.setImpltTrprZip(trprInfo.getImpltTrprZip()); + newTrprInfo.setImpltTrprAddr(trprInfo.getImpltTrprAddr()); + newTrprInfo.setImpltTrprDaddr(trprInfo.getImpltTrprDaddr()); + + // 행위 정보 설정 + newTrprInfo.setActNo(String.valueOf(actInfo.getActNo())); + newTrprInfo.setActTypeCd(actInfo.getActTypeCd()); + newTrprInfo.setLotnoMno(trprInfo.getLotnoMno()); + newTrprInfo.setLotnoSno(trprInfo.getLotnoSno()); + + crdnImpltTaskMapper.insertImpltTrprInfo(newTrprInfo); + } + } + log.debug("이행 대상자 정보 수정 완료: 소유자/행위자 {}명 * 행위 {}건 = 총 {}건", + vo.getImpltTrprInfoList().size(), actInfoList.size(), + vo.getImpltTrprInfoList().size() * actInfoList.size()); } } @@ -279,33 +371,6 @@ public class CrdnImpltTaskServiceImpl extends EgovAbstractServiceImpl implements list.sort(Comparator.comparing(CrdnImpltTrprInfoVO::getActNo) .thenComparing(CrdnImpltTrprInfoVO::getImpltTrprSeCd) .thenComparing(CrdnImpltTrprInfoVO::getImpltTrprFlnm)); - - // 중요로직: 행위 번호(actNo)의 홀/짝에 따라 그리드 행에 CSS 클래스를 적용 - for (CrdnImpltTrprInfoVO item : list) { - try { - if (item.getActNo() != null && !item.getActNo().isEmpty()) { - // actNo를 정수로 변환 - int actNo = Integer.parseInt(item.getActNo()); - - // TUI Grid _attributes 설정 - Map attributes = new HashMap<>(); - Map className = new HashMap<>(); - List rowClass = new ArrayList<>(); - - if (actNo % 2 == 0) { - rowClass.add(TuiGridColorConstants.ROW_COLOR_RED); - } else { - rowClass.add(TuiGridColorConstants.ROW_COLOR_BLUE); - } - className.put("row", rowClass); - attributes.put("className", className); - item.set_attributes(attributes); - } - } catch (NumberFormatException e) { - // actNo가 숫자가 아닌 경우 로그를 남기거나 무시 - log.warn("actNo is not a valid integer: {}", item.getActNo()); - } - } return list; } diff --git a/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskMapper_maria.xml b/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskMapper_maria.xml index 6b3047c..980f16e 100644 --- a/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskMapper_maria.xml +++ b/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/main/CrdnImpltTaskMapper_maria.xml @@ -195,10 +195,11 @@ + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTask/impltTaskPopup.jsp b/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTask/impltTaskPopup.jsp index 59d33cc..64de113 100644 --- a/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTask/impltTaskPopup.jsp +++ b/src/main/webapp/WEB-INF/views/crdn/crndRegistAndView/main/crdnImpltTask/impltTaskPopup.jsp @@ -168,8 +168,6 @@ getGridColumns: function() { var self = this; return [ - {header: '행위번호', name: 'actNo', align: 'center', width: 60}, - {header: '행위구분', name: 'actTypeCdNm', align: 'center', width: 120}, {header: '소유자, 행위자 구분', name: 'impltTrprSeCdNm', align: 'center', width: 120}, {header: '성명', name: 'impltTrprFlnm', align: 'center', width: 120}, {header: '우편번호', name: 'impltTrprZip', align: 'center', width: 80}, @@ -184,7 +182,6 @@ {header: '지번 본번', name: 'lotnoMno', align: 'right', width: 90, hidden: true}, {header: '지번 부번', name: 'lotnoSno', align: 'right', width: 90, hidden: true}, { header: '소유자 행위자 정보 ID', name: 'ownrActrInfoId', align: 'center', width: 120, hidden: true }, - { header: '이행 대상자 정보 ID', name: 'impltTrprInfoId', align: 'center', width: 120, hidden: true }, { header: '체크박스여부', name: 'selected', align: 'center', width: 120, hidden: true }, { header: '주민번호', name: 'rrno', align: 'center', width: 120, hidden: true }, ]; @@ -256,7 +253,9 @@ self.instance.disableRowCheck(row.rowKey); } }else{ - self.instance.check(row.rowKey); + if (row.selected ) { + self.instance.check(row.rowKey); + } } }); @@ -429,11 +428,6 @@ return; } - // 행위별로 최소 1명 이상 선택되었는지 검증 - if (!this.validateActNoSelection(selectedTrprInfoList)) { - return; - } - // 이행 대상자 정보를 formData에 추가 for (var i = 0; i < selectedTrprInfoList.length; i++) { var trprInfo = selectedTrprInfoList[i]; @@ -506,8 +500,6 @@ impltTrprZip: rowData.impltTrprZip, impltTrprAddr: rowData.impltTrprAddr, impltTrprDaddr: rowData.impltTrprDaddr, - actNo: rowData.actNo, - actTypeCd: rowData.actTypeCd, lotnoMno: rowData.lotnoMno, lotnoSno: rowData.lotnoSno }; @@ -545,48 +537,6 @@ return true; }, - /** - * 행위별 선택 검증 - * 중요한 로직 주석: 각 행위번호별로 최소 1명 이상의 이행 대상자가 선택되었는지 검증합니다. - * @param {Array} selectedTrprInfoList - 선택된 이행 대상자 정보 배열 - * @returns {boolean} 검증 성공 여부 - */ - validateActNoSelection: function(selectedTrprInfoList) { - // 전체 그리드 데이터에서 고유한 행위번호 목록 추출 - var allData = this.grid.instance.getData(); - var actNoSet = new Set(); - - for (var i = 0; i < allData.length; i++) { - if (allData[i].actNo) { - actNoSet.add(allData[i].actNo); - } - } - - // 선택된 데이터에서 행위번호별 개수 집계 - var selectedActNoMap = {}; - for (var i = 0; i < selectedTrprInfoList.length; i++) { - var actNo = selectedTrprInfoList[i].actNo; - if (actNo) { - selectedActNoMap[actNo] = (selectedActNoMap[actNo] || 0) + 1; - } - } - - // 각 행위번호별로 최소 1명 이상 선택되었는지 확인 - var missingActNos = []; - actNoSet.forEach(function(actNo) { - if (!selectedActNoMap[actNo] || selectedActNoMap[actNo] === 0) { - missingActNos.push(actNo); - } - }); - - // 선택되지 않은 행위번호가 있으면 경고 - if (missingActNos.length > 0) { - alert('행위번호 ' + missingActNos.join(', ') + '번의 이행 대상자를 최소 1명 이상 선택해주세요.'); - return false; - } - - return true; - }, };