From 2fc0c3ffd2e4ffa106ccda01299765ea1da5a965 Mon Sep 17 00:00:00 2001 From: mjkhan21 Date: Thu, 26 Jun 2025 12:13:46 +0900 Subject: [PATCH] =?UTF-8?q?=EC=97=AC=EB=9F=AC=EA=B0=9C=20=EB=8B=A8?= =?UTF-8?q?=EC=86=8D=EB=93=B1=EB=A1=9D=20=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xit/fims/cmmn/hwp/format/CrdnList.java | 10 +- src/main/java/cokr/xit/fims/crdn/Crdn.java | 3 + .../xit/fims/crdn/dao/CrdnStngMapper.java | 7 + .../xit/fims/crdn/dao/ExmptnVhclMapper.java | 3 + .../receive/eqpmnt/AttachedTxtParser.java | 4 +- .../xit/fims/crdn/service/CrdnService.java | 40 +- .../xit/fims/crdn/service/bean/CrdnBean.java | 151 ++++++-- .../crdn/service/bean/CrdnServiceBean.java | 32 +- .../crdn/service/bean/ImportServiceBean.java | 148 +++---- .../crdn/service/bean/ImportServiceBean2.java | 363 ++++++++++++++++++ .../xit/fims/crdn/web/Crdn05Controller.java | 24 +- .../fims/mngt/service/bean/TaskProcessor.java | 73 +++- .../sql/mapper/fims/crdn/crdn-inst-mapper.xml | 13 +- .../sql/mapper/fims/crdn/crdn-stng-mapper.xml | 22 +- .../mapper/fims/crdn/exmptn-vhcl-mapper.xml | 11 + 15 files changed, 744 insertions(+), 160 deletions(-) create mode 100644 src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean2.java diff --git a/src/main/java/cokr/xit/fims/cmmn/hwp/format/CrdnList.java b/src/main/java/cokr/xit/fims/cmmn/hwp/format/CrdnList.java index 101482b9..b0ea2ebe 100644 --- a/src/main/java/cokr/xit/fims/cmmn/hwp/format/CrdnList.java +++ b/src/main/java/cokr/xit/fims/cmmn/hwp/format/CrdnList.java @@ -8,6 +8,7 @@ import cokr.xit.applib.Print; import cokr.xit.applib.hwp.format.HWPFormat; import cokr.xit.fims.cmmn.FimsPrintOption; import cokr.xit.fims.mngt.OgdpUtil; +import cokr.xit.foundation.Assert; import cokr.xit.foundation.data.DataFormat; import cokr.xit.foundation.data.DataObject; @@ -69,8 +70,11 @@ public class CrdnList extends HWPFormat { instNm = OgdpUtil.getLastWord(instNm); writer.setValue("발신", instNm); - List list = IntStream.rangeClosed(1, this.data.size()).boxed().map(i -> { - DataObject one = data.get(i-1); + List list = IntStream.range(0, this.data.size()).boxed().map(i -> { + DataObject one = data.get(i); + String sttsChgDt = one.string("CRDN_STTS_CHG_DT"); + if (!Assert.isEmpty(sttsChgDt)) + sttsChgDt = sttsChgDt.substring(0, 8); return (DataObject) new DataObject() .set("과태료", one.string("TASK_SE_NM")) .set("시군구명", one.string("SGG_NM")) @@ -83,7 +87,7 @@ public class CrdnList extends HWPFormat { .set("가상계좌번호", one.string("VR_ACTNO")) .set("전자납부번호", one.string("EPAYNO")) .set("처리상태", one.string("CRDN_STTS_NM")) - .set("처리일자", DataFormat.yyyy_mm_dd(one.string("CRDN_STTS_CHG_DT").substring(0, 8))) + .set("처리일자", DataFormat.yyyy_mm_dd(sttsChgDt)) .set("납부기한", DataFormat.yyyy_mm_dd(one.string("DUDT_YMD"))) .set("수납일자", DataFormat.yyyy_mm_dd(one.string("RCVMT_YMD"))); }).toList(); diff --git a/src/main/java/cokr/xit/fims/crdn/Crdn.java b/src/main/java/cokr/xit/fims/crdn/Crdn.java index a636af18..a226e13c 100644 --- a/src/main/java/cokr/xit/fims/crdn/Crdn.java +++ b/src/main/java/cokr/xit/fims/crdn/Crdn.java @@ -2,6 +2,7 @@ package cokr.xit.fims.crdn; import java.util.List; +import cokr.xit.base.file.FileInfo; import cokr.xit.fims.payer.Payer; import cokr.xit.foundation.AbstractEntity; import cokr.xit.foundation.Assert; @@ -178,6 +179,8 @@ public class Crdn extends AbstractEntity { /** 클린파킹 키 */ private String mmCode; + private List attachments; + public static final String location(Object obj) { if (Assert.isEmpty(obj)) return ""; diff --git a/src/main/java/cokr/xit/fims/crdn/dao/CrdnStngMapper.java b/src/main/java/cokr/xit/fims/crdn/dao/CrdnStngMapper.java index 69c106a8..587eab1c 100644 --- a/src/main/java/cokr/xit/fims/crdn/dao/CrdnStngMapper.java +++ b/src/main/java/cokr/xit/fims/crdn/dao/CrdnStngMapper.java @@ -5,11 +5,18 @@ import java.util.Map; import org.egovframe.rte.psl.dataaccess.mapper.Mapper; +import cokr.xit.fims.crdn.Crdn; import cokr.xit.fims.crdn.CrdnQuery; import cokr.xit.foundation.component.AbstractMapper; +import cokr.xit.foundation.data.DataObject; @Mapper("crdnStngMapper") public interface CrdnStngMapper extends AbstractMapper { + /**중복 단속 리스트를 조회한다. + * @param crdns 단속 목록 + * @return 중복 단속 목록 + */ + List selectDuplicateCrdns(List crdns); /**기본금액을 조회한다.
* {@link cokr.xit.fims.crdn.service.bean.CrdnStngBean#getBasicAmt(CrdnQuery)} 참고 * @param query 단속자료 정보 diff --git a/src/main/java/cokr/xit/fims/crdn/dao/ExmptnVhclMapper.java b/src/main/java/cokr/xit/fims/crdn/dao/ExmptnVhclMapper.java index a75f6bc7..aae1fa12 100644 --- a/src/main/java/cokr/xit/fims/crdn/dao/ExmptnVhclMapper.java +++ b/src/main/java/cokr/xit/fims/crdn/dao/ExmptnVhclMapper.java @@ -4,6 +4,7 @@ import java.util.List; import org.egovframe.rte.psl.dataaccess.mapper.Mapper; +import cokr.xit.fims.crdn.Crdn; import cokr.xit.fims.crdn.CrdnQuery; import cokr.xit.fims.crdn.ExmptnVhcl; import cokr.xit.foundation.component.AbstractMapper; @@ -11,6 +12,8 @@ import cokr.xit.foundation.data.DataObject; @Mapper("exmptnVhclMapper") public interface ExmptnVhclMapper extends AbstractMapper { + List selectExemptedCrdns(List crdns); + /**면제차량 목록을 조회한다.
* @param query 면제차량 목록 조회 조건 * @return 면제차량 목록 diff --git a/src/main/java/cokr/xit/fims/crdn/receive/eqpmnt/AttachedTxtParser.java b/src/main/java/cokr/xit/fims/crdn/receive/eqpmnt/AttachedTxtParser.java index 12884dc2..b0cfc528 100644 --- a/src/main/java/cokr/xit/fims/crdn/receive/eqpmnt/AttachedTxtParser.java +++ b/src/main/java/cokr/xit/fims/crdn/receive/eqpmnt/AttachedTxtParser.java @@ -26,10 +26,8 @@ public class AttachedTxtParser extends LayoutParser{ public void analyzeFileContent(DataObject dataObject, File file) { try { JSONArray jsonArray = (JSONArray)new JSONParser(-1).parse(descriptor.getContentItems()); - boolean isMetaData = dataObject.string("FILE_EXTENSION").toUpperCase().equals("TXT"); - + boolean isMetaData = "TXT".equalsIgnoreCase(dataObject.string("FILE_EXTENSION")); if (isMetaData) { - BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),Charset.forName(ifEmpty(FimsConf.get().getTxtCharset(), "UTF-8")))); String content = IOUtils.toString(br); String[] contentDivision = null; diff --git a/src/main/java/cokr/xit/fims/crdn/service/CrdnService.java b/src/main/java/cokr/xit/fims/crdn/service/CrdnService.java index d6696c08..6fa727c7 100644 --- a/src/main/java/cokr/xit/fims/crdn/service/CrdnService.java +++ b/src/main/java/cokr/xit/fims/crdn/service/CrdnService.java @@ -25,22 +25,28 @@ public interface CrdnService { */ DataObject getCrackdownInfo(CrdnQuery query); + /** 단속자료 건수를 조회한다. + * @param crdnQuery 단속자료 조회조건 + * @return 단속자료 건수 + */ + int countCrdn(CrdnQuery crdnQuery); + List getCrackdowns(List crdnIds); Crdn getCrackdown(String crdnId); - /** 단속자료를 삭제한다. - * @param crdnIds 삭제할 단속자료 ID 목록 - * @return 삭제여부 - */ - String remove(String... crdnIds); - /** 단속 자료를 신규 등록한다. * @param nonQueryRequest 등록 요청, crdn 단속정보, newFileList 업로드 파일 목록 * @return 저장여부 */ String create(Map nonQueryRequest, Crdn crdn, List newFileInfoList); + /** 단속 자료를 수정한다. + * @param crdn 단속정보 + * @return 저장 메시지 + */ + String updateCrackdown(Crdn crdn); + String updateVehicleOwners(InputStream upload, List crdnIds); /** 시간초과 정보를 변경하고, 금액을 증가 또는 감소시킨다. @@ -55,11 +61,11 @@ public interface CrdnService { */ String updateTagInfo(Crdn crdn); - /** 단속 자료를 수정한다. + /** 단속 자료의 처리 상태 코드를 수정한다. * @param crdn 단속정보 * @return 저장 메시지 */ - String updateCrackdown(Crdn crdn); + String updateCrackdownStatus(Crdn crdn); /** 단속 자료를 삭제한다. * @param crdn 단속정보 @@ -67,17 +73,17 @@ public interface CrdnService { */ String removeCrackdown(Crdn crdn); - /** 단속 자료의 납부자 ID를 삭제한다. - * @param crdn 단속정보 - * @return 저장 메시지 + /** 단속자료를 삭제한다. + * @param crdnIds 삭제할 단속자료 ID 목록 + * @return 삭제여부 */ - String removeCrackdownPayer(Crdn crdn); + String remove(String... crdnIds); - /** 단속 자료의 처리 상태 코드를 수정한다. + /** 단속 자료의 납부자 ID를 삭제한다. * @param crdn 단속정보 * @return 저장 메시지 */ - String updateCrackdownStatus(Crdn crdn); + String removeCrackdownPayer(Crdn crdn); /** 장비 연계파일을 삭제한다. * @param entType 업체유형, fileName 파일명 @@ -90,10 +96,4 @@ public interface CrdnService { * @return 처리 결과 메시지 */ String changeCrdnImageFile(Crdn crdn, List> processList); - - /** 단속자료 건수를 조회한다. - * @param crdnQuery 단속자료 조회조건 - * @return 단속자료 건수 - */ - int countCrdn(CrdnQuery crdnQuery); } \ No newline at end of file diff --git a/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java b/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java index c2c13864..b50206a7 100644 --- a/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java +++ b/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnBean.java @@ -4,7 +4,9 @@ import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,7 +34,9 @@ import cokr.xit.fims.excl.service.bean.LevyExclBean; import cokr.xit.fims.mngt.service.bean.TaskProcessor; import cokr.xit.foundation.UserInfo; import cokr.xit.foundation.component.AbstractBean; +import cokr.xit.foundation.data.DataFormat; import cokr.xit.foundation.data.DataObject; +import cokr.xit.foundation.data.DataProc; /** 단속 관리 Bean * @author leebj @@ -58,15 +62,109 @@ public class CrdnBean extends AbstractBean { @Resource(name = "levyExclBean") protected LevyExclBean levyExclBean; + public List create(List crdns, boolean exclude) { + TaskProcessor taskProcessor = TaskProcessor.get(); + List duplicates = taskProcessor.getDuplicates(crdns), // 중복 단속목록 + distincts = crdns.stream().filter(crdn -> !duplicates.contains(crdn)).toList(); // 중복되지 않는 단속목록 + + ArrayList result = new ArrayList<>(); + duplicates.forEach(crdn -> result.add( + new DataProc() + .setTarget(crdn) + .setSuccess(false) + .setInfo("reason", "duplicate") + )); + if (distincts.isEmpty()) + return result; + + Map levyExcls = exclude ? taskProcessor.getExcluded(distincts) : Collections.emptyMap(); + + for (Crdn crdn: distincts) { + String sggCd = crdn.getSggCd(); + String taskSeCd = crdn.getTaskSeCd(); + List attachments = crdn.getAttachments(); + crdn.setAtchFileCnt(isEmpty(attachments) ? 0 : attachments.size()); + + setAmount(crdn); + //단속팀 정보 갱신 + if (!isEmpty(crdn.getTeamId())) { + DataObject teamInfo = crdnTeamMapper.selectTeamInfo(crdn.getTeamId()); + + Team team = new Team(); + team.setTaskSeCd(taskSeCd); + team.setSggCd(sggCd); + team.setTeamNm(teamInfo.string("TEAM_NM")); + team.setCrdnSeCd(crdn.getCrdnSeCd()); + team.setTeamer1(crdn.getTeamer1()); + team.setTeamer2(crdn.getTeamer2()); + team.setTeamer3(crdn.getTeamer3()); + team.setTeamer4(crdn.getTeamer4()); + + crdnStngBean.saveTeamInfo(true, team); + } + //상태코드 설정 + if (isEmpty(crdn.getCrdnSttsCd())){ //상태코드가 없을경우 + if ("Y".equals(crdn.getCvlcptLinkYn())) { //민원연계자료일 경우 + crdn.setCrdnSttsCd("01"); //초기상태 + } else { //민원연계자료가 아닐 경우 + crdn.setCrdnSttsCd(isEmpty(crdn.getRtpyrId()) ? "01" : "21"); // 01: 초기상태 21: 납부자등록완료 + } + crdn.setCrdnSttsChgDt(dateFormats.now()); + } + + //단속 대장 등록 + createLedger(crdn); + + LevyExcl excl01 = levyExcls.get(crdn); + if (excl01 != null) { + excl01.setCrdnId(crdn.getCrdnId()); + levyExclBean.createLevyExcl(excl01); + } else { + // 단속상태이력(TB_CRDN_STTS_HSTRY) 대장 등록 + CrdnSttsHstry crdnSttsHstry = new CrdnSttsHstry(); + crdnSttsHstry.setCrdnId(crdn.getCrdnId()); + crdnSttsHstry.setBfrSttsCd(""); + crdnSttsHstry.setBfrSttsChgDt(""); + crdnSttsHstry.setCrdnSttsCd(crdn.getCrdnSttsCd()); + crdnSttsHstry.setTaskDtlId(crdn.getCrdnId()); + crdnSttsHstry.setEtcCn(""); + + crdnSttsHstryBean.create(crdnSttsHstry); + } + + //단속납부자이력(TB_CRDN_PAYER_HSTRY) 대장 등록 + if (!isEmpty(crdn.getRtpyrId())) { + CrdnPayerAddrHstry crdnPayerAddrHstry = new CrdnPayerAddrHstry(); + crdnPayerAddrHstry.setCrdnId(crdn.getCrdnId()); + crdnPayerAddrHstry.setRtpyrId(crdn.getRtpyrId()); + crdnPayerAddrHstry.setAddrSn(crdn.getAddrSn()); + + // 단속 대장의 납부자ID 수정 및 단속 납부자 이력(TB_CRDN_PAYER_HSTRY) 대장에 등록한다. + crdnPayerAddrHstryBean.createCrdnPayerAddrHstry(crdnPayerAddrHstry); + } + + //파일 등록 + if (!isEmpty(attachments)) { + attachments.forEach(fileInfo -> fileInfo.setInfoType(Crdn.INF_TYPE).setInfoKey(crdn.getCrdnId())); + fileBean.create(attachments); + } + + DataProc dataProc = new DataProc().setTarget(crdn); + String ersrRegYmd = crdn.getErsrRegYmd(); + if (!isEmpty(ersrRegYmd)) + dataProc.setInfo("erased", new DataObject().set("vhrno", crdn.getVhrno()).set("date", DataFormat.yyyy_mm_dd(ersrRegYmd))); + result.add(dataProc); + } + + return result; + } + public boolean create(Map nonQueryRequest, Crdn crdn, List fileInfoList) { String sggCd = crdn.getSggCd(); String taskSeCd = crdn.getTaskSeCd(); crdn.setAtchFileCnt(isEmpty(fileInfoList) ? 0 : fileInfoList.size()); - //금액 계산 - int[] basicAmt = crdnStngBean.getBasicAmt(crdn); - crdn.setFfnlgCrdnAmt(basicAmt[0]); - crdn.setFfnlgAmt(basicAmt[0]); - crdn.setAdvntceAmt(basicAmt[1]); + + setAmount(crdn); //단속팀 정보 갱신 if (!isEmpty(crdn.getTeamId())) { @@ -147,6 +245,13 @@ public class CrdnBean extends AbstractBean { return result; } + private void setAmount(Crdn crdn) { + int[] basicAmt = crdnStngBean.getBasicAmt(crdn); + crdn.setFfnlgCrdnAmt(basicAmt[0]); + crdn.setFfnlgAmt(basicAmt[0]); + crdn.setAdvntceAmt(basicAmt[1]); + } + /**단속 대장 정보를 등록한다. * @param crdn 단속 대장 * @return 저장 여부 @@ -158,21 +263,6 @@ public class CrdnBean extends AbstractBean { return crdnInstMapper.insert(crdn); } - /**단속 정보를 삭제한다. - * @param crdnIds 단속아이디 목록 - * @return 저장 여부 - *
  • 저장됐으면 true
  • - *
  • 그렇지 않으면 false
  • - *
- */ - public boolean remove(String... crdnIds) { - return !isEmpty(crdnIds) - && crdnUpdtMapper.deleteCrdn(new DataObject() - .set("crdnIds", crdnIds) - .set("removedBy", UserInfo.current().getId()) - ) >= 1; - } - /**단속 자료를 수정한다. * @param crdn 단속 * @return 저장 여부 @@ -181,11 +271,7 @@ public class CrdnBean extends AbstractBean { * */ public String updateCrackdown(Crdn crdn) { - //금액 계산 - int[] basicAmt = crdnStngBean.getBasicAmt(crdn); - crdn.setFfnlgCrdnAmt(basicAmt[0]); - crdn.setFfnlgAmt(basicAmt[0]); - crdn.setAdvntceAmt(basicAmt[1]); + setAmount(crdn); // 단속(TB_CRDN) 대장을 수정한다. if (crdnUpdtMapper.updateEditCrdn(crdn) != 1) @@ -314,6 +400,21 @@ public class CrdnBean extends AbstractBean { return "[S] 작업이 정상 처리 되었습니다."; } + /**단속 정보를 삭제한다. + * @param crdnIds 단속아이디 목록 + * @return 저장 여부 + *
  • 저장됐으면 true
  • + *
  • 그렇지 않으면 false
  • + *
+ */ + public boolean remove(String... crdnIds) { + return !isEmpty(crdnIds) + && crdnUpdtMapper.deleteCrdn(new DataObject() + .set("crdnIds", crdnIds) + .set("removedBy", UserInfo.current().getId()) + ) >= 1; + } + /** 장비 연계파일을 삭제한다. * @param workPath 작업 디렉토리, fileName 파일명 * @return 저장 여부 diff --git a/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnServiceBean.java b/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnServiceBean.java index 6bfcfe31..a37269df 100644 --- a/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnServiceBean.java +++ b/src/main/java/cokr/xit/fims/crdn/service/bean/CrdnServiceBean.java @@ -163,6 +163,11 @@ public class CrdnServiceBean extends AbstractServiceBean implements CrdnService return crdnInfoMapper.selectCrdnInfo(query.getCrdnId()); } + @Override + public int countCrdn(CrdnQuery crdnQuery) { + return crdnListMapper.countCrdn(crdnQuery); + } + @Override public List getCrackdowns(List crdnIds) { return crdnInfoMapper.selectCrdns(crdnIds); @@ -174,13 +179,13 @@ public class CrdnServiceBean extends AbstractServiceBean implements CrdnService } @Override - public String remove(String... crdnIds) { - return crdnBean.remove(crdnIds) ? "[S]" : "[F]단속 자료 삭제 중 오류가 발생하였습니다."; + public String create(Map nonQueryRequest, Crdn crdn, List fileInfoList) { + return crdnBean.create(nonQueryRequest, crdn, fileInfoList) ? "[S]" : "[F]단속 자료 등록 중 오류가 발생하였습니다."; } @Override - public String create(Map nonQueryRequest, Crdn crdn, List fileInfoList) { - return crdnBean.create(nonQueryRequest, crdn, fileInfoList) ? "[S]" : "[F]단속 자료 등록 중 오류가 발생하였습니다."; + public String updateCrackdown(Crdn crdn) { + return crdnBean.updateCrackdown(crdn); } @Override @@ -273,8 +278,13 @@ public class CrdnServiceBean extends AbstractServiceBean implements CrdnService } @Override - public String updateCrackdown(Crdn crdn) { - return crdnBean.updateCrackdown(crdn); + public String updateCrackdownStatus(Crdn crdn) { + return crdnBean.updateCrackdownStatus(crdn); + } + + @Override + public String remove(String... crdnIds) { + return crdnBean.remove(crdnIds) ? "[S]" : "[F]단속 자료 삭제 중 오류가 발생하였습니다."; } @Override @@ -287,11 +297,6 @@ public class CrdnServiceBean extends AbstractServiceBean implements CrdnService return crdnBean.removeCrackdownPayer(crdn); } - @Override - public String updateCrackdownStatus(Crdn crdn) { - return crdnBean.updateCrackdownStatus(crdn); - } - @Override public String removeEquipmentLinkFile(String workPath, String fileName) { return crdnBean.removeEquipmentLinkFile(workPath, fileName) ? "[S]" : "[F]장비연계파일 삭제 중 오류가 발생하였습니다."; @@ -343,9 +348,4 @@ public class CrdnServiceBean extends AbstractServiceBean implements CrdnService return "[S] 작업이 정상 처리 되었습니다."; } - - @Override - public int countCrdn(CrdnQuery crdnQuery) { - return crdnListMapper.countCrdn(crdnQuery); - } } \ No newline at end of file diff --git a/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java b/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java index 67adc57b..0dd2a296 100644 --- a/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java +++ b/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean.java @@ -4,7 +4,7 @@ import java.io.File; import java.math.BigInteger; import java.util.ArrayList; import java.util.Comparator; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -20,7 +20,6 @@ import cokr.xit.base.file.web.FileInfoFactory; import cokr.xit.base.user.dao.UserMapper; import cokr.xit.fims.cmmn.CmmnUtil; import cokr.xit.fims.crdn.Crdn; -import cokr.xit.fims.crdn.CrdnQuery; import cokr.xit.fims.crdn.Team; import cokr.xit.fims.crdn.dao.CrdnTeamMapper; import cokr.xit.fims.crdn.receive.eqpmnt.SingleFileParser; @@ -29,6 +28,7 @@ import cokr.xit.fims.crdn.service.ImportService; import cokr.xit.fims.mngt.service.bean.TaskProcessor; import cokr.xit.foundation.component.AbstractServiceBean; import cokr.xit.foundation.data.DataObject; +import cokr.xit.foundation.data.DataProc; import cokr.xit.interfaces.smg.Petition; import cokr.xit.interfaces.smg.service.bean.SmgReceiverBean; @@ -87,6 +87,7 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ @Override public Map createCrdnByEquipmentLinkFile(Map processInfo, List fileList) { + DataObject resp = new DataObject().set("received", fileList.size()); String workPath = processInfo.get("workPath"); String taskSeCd = processInfo.get("taskSeCd"); String orgID = currentUser().getOrgID(); @@ -95,26 +96,38 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ excludeExempted = "true".equals(processInfo.get("excludeExempted")), cctv = isEmpty(workPath); - List crdnList = divideFiles(fileList).stream() - .map(dividedInfo -> { - Crdn crdn = new Crdn(); - crdn.setCrdnRegSeCd("07"); - crdn.setTaskSeCd(taskSeCd); - crdn.setSggCd(orgID); + List divided = divideFiles(fileList); + resp.set("divided", divided.size()); + + List errors = divided.stream().filter(info -> info.get("metaInfo") == null).toList(); + divided.removeAll(errors); // 오류 항목 제외 + resp.set("normal", divided.size()) + .set("malformed", errors.size()); + log().debug("Before creating Crdns: {}", resp); + Map crdnMap = divided.stream() + .map(dividedInfo -> { + DataObject result = new DataObject(); DataObject metaInfo = (DataObject)dividedInfo.get("metaInfo"); + List imageList = CmmnUtil.getDataObjectListFromMap(dividedInfo,"imageInfo"); DataObject bgngData = (DataObject)dividedInfo.get("bgngData"); DataObject endData = (DataObject)dividedInfo.get("endData"); + //1. 연계파일정보를 단속 엔티티로 변환 - crdnTimeRangeSet(crdn, bgngData, endData); + Crdn crdn = new Crdn(); + crdn.setCrdnRegSeCd("07"); + crdn.setTaskSeCd(taskSeCd); + crdn.setSggCd(orgID); - String crdnInptSeCd = switch (blankIfEmpty(metaInfo.get("LINK_ENT_NM"))) { - case "ino" -> "11"; - case "knl" -> "12"; - default -> "15"; - }; - crdn.setCrdnInptSeCd(crdnInptSeCd); + crdnTimeRangeSet(crdn, bgngData, endData); + crdn.setCrdnInptSeCd( + switch (blankIfEmpty(metaInfo.get("LINK_ENT_NM"))) { + case "ino" -> "11"; + case "knl" -> "12"; + default -> "15"; + } + ); crdn.setVltnCd(ifEmpty(metaInfo.string("VLTN_CD"), () -> "01")); crdn.setCrdnSpareaCd(ifEmpty(metaInfo.string("CRDN_SPAREA_CD"), () -> "00")); @@ -151,70 +164,71 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ } //metaInfo.string("PLATE_WIDTH"); //metaInfo.string("PLATE_HEIGHT"); - List fileInfos = parseDataInfoToFileInfo(imageList, ifEmpty(fileGroupType, () -> metaInfo.string("FILE_GROUP_TYPE"))); - DataObject result = new DataObject() + List attachments = parseDataInfoToFileInfo(imageList, ifEmpty(fileGroupType, () -> metaInfo.string("FILE_GROUP_TYPE"))); + crdn.setAttachments(attachments); + result .set("crdn", crdn) - .set("fileInfos", fileInfos) +// .set("fileInfos", attachments) .set("files", cctv ? dividedInfo.get("files") : null); return result; }) - .toList(); - - List crdns = crdnList.stream() - .map(info -> (Crdn)info.get("crdn")) - .toList(); + .collect(Collectors.toMap( + info -> (Crdn)info.get("crdn"), + info -> info, + (org, rpl) -> org, + LinkedHashMap::new + )); + + List crdns = crdnMap.keySet().stream().toList(); //2. 차적 조회 importBean.setVehicleInfo(crdns); - List - vhrnos = crdns.stream().map(crdn -> crdn.getVhrno()).toList(), - exempted = crdnStngBean.selectExemptionVehicleList(new CrdnQuery().setVhrnos(vhrnos).setSggCd(orgID)) - .stream() - .map(row -> row.string("VHRNO")) - .toList(); - ArrayList success = new ArrayList<>(); - HashMap resultMap = new HashMap<>(); //3.등록 - crdnList.forEach(info -> { - Crdn crdn = (Crdn)info.get("crdn"); - if (exempted.contains(crdn.getVhrno()) && excludeExempted) - crdn.setCrdnSttsCd("81"); // 면제차량 - List fileInfoList = (List)info.get("fileInfos"); - boolean saved = crdnBean.create(null, crdn, fileInfoList); - resultMap.put("saved", saved); - if (saved) { - if (!isEmpty(crdn.getErsrRegYmd())) { - String vhrno = crdn.getVhrno(); - String ersrRegYmd = crdn.getErsrRegYmd(); - String ersrYear = ersrRegYmd.substring(0, 4); - String ersrMonth = ersrRegYmd.substring(4, 6); - String ersrDay = ersrRegYmd.substring(6, 8); - - resultMap.put("alertMessage", vhrno + " : " + ersrYear + "년" + ersrMonth + "월" + ersrDay + "일로 말소된 차량입니다."); - } - if (cctv) { - List files = (List)info.get("files"); - if (!isEmpty(files)) - success.addAll(files.stream().map(file -> (File)file.get("file")).toList()); - } - } else { - resultMap.put("failReason", "기타 오류"); + List dataProcs = crdnBean.create(crdns, excludeExempted); + LinkedHashMap> fileMap = new LinkedHashMap<>(); + String[] strs = {"success", "duplicate"}; + for (DataProc dataProc: dataProcs) { + Crdn crdn = dataProc.getTarget(); + DataObject info = crdnMap.get(crdn); + List files = (List)info.get("files"); + if (isEmpty(files)) continue; + + List extracted = files.stream().map(file -> (File)file.get("file")).toList(); + + for (String str: strs) { + List list = fileMap.get(str); + if (list == null) + fileMap.put(str, list = new ArrayList<>()); + if ("success".equals(str) && dataProc.isSuccess()) + list.addAll(extracted); + if ("duplicates".equals(str) && "duplicate".equals(dataProc.getInfo("reason"))) + list.addAll(extracted); } - }); + } + fileMap.put("fail", errors.stream().flatMap(info -> { + List tmp = ((List)info.get("files")); + return tmp.stream().map(file -> (File)file.get("file")); + }).toList()); + resp.set("success", dataProcs.stream().filter(DataProc::isSuccess).count()) + .set("duplicates", dataProcs.stream().filter(dp -> "duplicate".equals(dp.getInfo("reason"))).count()); + if (!isEmpty(workPath)) fileList.forEach(delInfo -> crdnBean.removeEquipmentLinkFile(workPath, delInfo.string("FILE_NAME"))); String dir = null; - for (File file: success) { - String srcDir = file.getParentFile().getAbsolutePath(), - destDir = srcDir.replace(File.separator + "work", File.separator + "success"); - if (!equals(dir, destDir)) - ensureDir(dir = destDir); - - file.renameTo(new File(destDir + File.separator + file.getName())); + for (Map.Entry> entry: fileMap.entrySet()) { + String key = entry.getKey(); + List files = entry.getValue(); + for (File file: files) { + String srcDir = file.getParentFile().getAbsolutePath(), + destDir = srcDir.replace(File.separator + "work", File.separator + key); + if (!equals(dir, destDir)) + ensureDir(dir = destDir); + + file.renameTo(new File(destDir + File.separator + file.getName())); + } } - - return resultMap; + return resp; } /**파싱된 데이터 목록을 메타정보, 이미지정보목록, 최초단속자료, 최종단속자료로 분리한다.
@@ -236,6 +250,7 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ DataObject first = files.get(0); String groupType = first.string("FILE_GROUP_TYPE"); + if ("TXT".equalsIgnoreCase(groupType)) { Optional found = files.stream() .filter(file -> "TXT".equalsIgnoreCase(file.string("FILE_EXTENSION"))) @@ -268,9 +283,10 @@ public class ImportServiceBean extends AbstractServiceBean implements ImportServ .set("bgngData", bgngAndEnd[0]) .set("endData", bgngAndEnd[1]) .set("files", files); + return result; }) - .toList(); + .collect(Collectors.toCollection(ArrayList::new)); } /**단속이미지정보 목록 내에서 최초단속자료와 최종단속자료를 반환한다. 단속일시 정보가 없을 경우 null을 반환한다.
diff --git a/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean2.java b/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean2.java new file mode 100644 index 00000000..f7a16352 --- /dev/null +++ b/src/main/java/cokr/xit/fims/crdn/service/bean/ImportServiceBean2.java @@ -0,0 +1,363 @@ +package cokr.xit.fims.crdn.service.bean; + +import java.io.File; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import javax.annotation.Resource; + +import cokr.xit.base.file.FileInfo; +import cokr.xit.base.file.service.bean.FileBean; +import cokr.xit.base.file.web.FileInfoFactory; +import cokr.xit.base.user.dao.UserMapper; +import cokr.xit.fims.cmmn.CmmnUtil; +import cokr.xit.fims.crdn.Crdn; +import cokr.xit.fims.crdn.CrdnQuery; +import cokr.xit.fims.crdn.Team; +import cokr.xit.fims.crdn.dao.CrdnTeamMapper; +import cokr.xit.fims.crdn.receive.eqpmnt.SingleFileParser; +import cokr.xit.fims.crdn.service.CrdnService; +import cokr.xit.fims.crdn.service.ImportService; +import cokr.xit.fims.mngt.service.bean.TaskProcessor; +import cokr.xit.foundation.component.AbstractServiceBean; +import cokr.xit.foundation.data.DataObject; +import cokr.xit.interfaces.smg.Petition; +import cokr.xit.interfaces.smg.service.bean.SmgReceiverBean; + +/**외부 연계 파일에서 단속자료를 추출하여 등록하는 서비스의 구현체 + * @author mjkhan + */ +//@Service("importService") +public class ImportServiceBean2 extends AbstractServiceBean implements ImportService { + @Resource(name = "smgReceiverBean") + private SmgReceiverBean smgBean; + @Resource(name = "importBean") + private ImportBean importBean; + @Resource(name = "fileBean") + private FileBean fileBean; + @Resource(name = "crdnService") + private CrdnService crdnService; + @Resource(name = "crdnBean") + private CrdnBean crdnBean; + @Resource(name = "crdnStngBean") + private CrdnStngBean crdnStngBean; + + @Resource(name="userMapper") + protected UserMapper userMapper; + @Resource(name = "crdnTeamMapper") + private CrdnTeamMapper crdnTeamMapper; + + @Override + public int createCrdns(List interfaceSequences) { + List petitions = smgBean.getPetitions(interfaceSequences); + List crdns = importBean.createCrdns(petitions); + if (crdns.isEmpty()) return 0; + + List intfSeqs = crdns.stream().map(Crdn::getCvlcptLinkId).toList(); + + List smgFileInfoList = fileBean.getFilesOf("010", intfSeqs.toArray(new String[intfSeqs.size()])); + Map> byInfoKey = smgFileInfoList.stream().collect(Collectors.groupingBy(FileInfo::getInfoKey)); + + for (Crdn crdn: crdns) { + List files = byInfoKey.get(crdn.getCvlcptLinkId()); + + files.removeIf(item -> item.getMimeType().startsWith("video")); + + for (FileInfo file : files) { + file.setInputStream(file.getInputStream()); //신규 인풋스트림 생성 + file.setUrl(""); //인터페이스 첨부파일정보 제거 + file.setPath(""); //국민신문고 첨부파일정보 제거 + } + + crdn.setCvlcptLinkYn("Y"); + crdnBean.create(null, crdn, files); + } + + importBean.createCvlcpts(petitions); + return 0; + } + + @Override + public Map createCrdnByEquipmentLinkFile(Map processInfo, List fileList) { + String workPath = processInfo.get("workPath"); + String taskSeCd = processInfo.get("taskSeCd"); + String orgID = currentUser().getOrgID(); + String fileGroupType = processInfo.get("fileGroupType"); + boolean statByTeamEquipment = TaskProcessor.get().statByTeamEquipment(taskSeCd), + excludeExempted = "true".equals(processInfo.get("excludeExempted")), + cctv = isEmpty(workPath); + + List divided = divideFiles(fileList); + List errors = divided.stream().filter(info -> !isEmpty(info.get("error"))).toList(); + divided.removeAll(errors); // 오류 있는 항목들을 제외 + log().debug("divided: {}, errors: {}", divided.size(), errors.size()); + errors.forEach(row -> log().debug("error: {}", row)); + List crdnList = divided.stream() + .map(dividedInfo -> { + DataObject result = new DataObject(); + DataObject metaInfo = (DataObject)dividedInfo.get("metaInfo"); + + List imageList = CmmnUtil.getDataObjectListFromMap(dividedInfo,"imageInfo"); + DataObject bgngData = (DataObject)dividedInfo.get("bgngData"); + DataObject endData = (DataObject)dividedInfo.get("endData"); + + //1. 연계파일정보를 단속 엔티티로 변환 + Crdn crdn = new Crdn(); + crdn.setCrdnRegSeCd("07"); + crdn.setTaskSeCd(taskSeCd); + crdn.setSggCd(orgID); + + crdnTimeRangeSet(crdn, bgngData, endData); + + String crdnInptSeCd = switch (blankIfEmpty(metaInfo.get("LINK_ENT_NM"))) { + case "ino" -> "11"; + case "knl" -> "12"; + default -> "15"; + }; + crdn.setCrdnInptSeCd(crdnInptSeCd); + crdn.setVltnCd(ifEmpty(metaInfo.string("VLTN_CD"), () -> "01")); + crdn.setCrdnSpareaCd(ifEmpty(metaInfo.string("CRDN_SPAREA_CD"), () -> "00")); + + crdn.setVhrno(metaInfo.string("VHRNO")); + crdn.setCrdnYmd(metaInfo.string("CRDN_YMD")); + crdn.setCrdnTm(metaInfo.string("CRDN_TM")); + if (isEmpty(crdn.getCrdnBgngTm())) { + crdn.setCrdnBgngTm(metaInfo.string("CRDN_BGNG_TM")); + crdn.setCrdnEndTm(metaInfo.string("CRDN_END_TM")); + } + + crdn.setGpsX(metaInfo.string("GPS_X")); + crdn.setGpsY(metaInfo.string("GPS_Y")); + crdn.setCrdnPlc(metaInfo.string("CRDN_PLC")); + crdn.setCrdnRoadNm(metaInfo.string("CRDN_ROAD_NM")); + crdn.setCrdnStdgNm(metaInfo.string("CRDN_STDG_NM")); + + crdn.setCrdnSeCd(metaInfo.string("CRDN_SE_CD")); + crdn.setMoscX(metaInfo.string("MOSC_X")); + crdn.setMoscY(metaInfo.string("MOSC_Y")); + + if (statByTeamEquipment) { + if (!isEmpty(crdn.getCrdnSeCd()) && !isEmpty(metaInfo.string("EQPMNT_CD"))) { + Team team = new Team(); + team.setSggCd(crdn.getSggCd()); + team.setTaskSeCd(taskSeCd); + team.setTeamNm(metaInfo.string("EQPMNT_CD")); + DataObject teamInfo = crdnTeamMapper.selectTeamInfoByName(team); + + if (teamInfo != null && crdn.getCrdnSeCd().equals(teamInfo.string("CRDN_SE_CD"))) { + crdn.setTeamId(teamInfo.string("TEAM_ID")); + } + } + } + //metaInfo.string("PLATE_WIDTH"); + //metaInfo.string("PLATE_HEIGHT"); + List fileInfos = parseDataInfoToFileInfo(imageList, ifEmpty(fileGroupType, () -> metaInfo.string("FILE_GROUP_TYPE"))); + result + .set("crdn", crdn) + .set("fileInfos", fileInfos) + .set("files", cctv ? dividedInfo.get("files") : null); + return result; + }) + .toList(); + + List crdns = crdnList.stream() + .map(info -> (Crdn)info.get("crdn")) + .toList(); + //2. 차적 조회 + importBean.setVehicleInfo(crdns); + + List + vhrnos = crdns.stream().map(crdn -> crdn.getVhrno()).toList(), + exempted = crdnStngBean.selectExemptionVehicleList(new CrdnQuery().setVhrnos(vhrnos).setSggCd(orgID)) + .stream() + .map(row -> row.string("VHRNO")) + .toList(); + ArrayList success = new ArrayList<>(); + HashMap resultMap = new HashMap<>(); + //3.등록 + crdnList.forEach(info -> { + Crdn crdn = (Crdn)info.get("crdn"); + if (exempted.contains(crdn.getVhrno()) && excludeExempted) + crdn.setCrdnSttsCd("81"); // 면제차량 + List fileInfoList = (List)info.get("fileInfos"); + boolean saved = crdnBean.create(null, crdn, fileInfoList); + resultMap.put("saved", saved); + if (saved) { + if (!isEmpty(crdn.getErsrRegYmd())) { + String vhrno = crdn.getVhrno(); + String ersrRegYmd = crdn.getErsrRegYmd(); + String ersrYear = ersrRegYmd.substring(0, 4); + String ersrMonth = ersrRegYmd.substring(4, 6); + String ersrDay = ersrRegYmd.substring(6, 8); + + resultMap.put("alertMessage", vhrno + " : " + ersrYear + "년" + ersrMonth + "월" + ersrDay + "일로 말소된 차량입니다."); + } + if (cctv) { + List files = (List)info.get("files"); + if (!isEmpty(files)) + success.addAll(files.stream().map(file -> (File)file.get("file")).toList()); + } + } else { + resultMap.put("failReason", "기타 오류"); + } + }); + if (!isEmpty(workPath)) + fileList.forEach(delInfo -> crdnBean.removeEquipmentLinkFile(workPath, delInfo.string("FILE_NAME"))); + + String dir = null; + for (File file: success) { + String srcDir = file.getParentFile().getAbsolutePath(), + destDir = srcDir.replace(File.separator + "work", File.separator + "success"); + if (!equals(dir, destDir)) + ensureDir(dir = destDir); + + file.renameTo(new File(destDir + File.separator + file.getName())); + } + + return resultMap; + } + + /**파싱된 데이터 목록을 메타정보, 이미지정보목록, 최초단속자료, 최종단속자료로 분리한다.
+ * @param fileList 연계파일정보목록, fileGroupType 연계파일그룹형식 + * @return 메타정보, 이미지정보목록, 최초단속자료, 최종단속자료 + */ + private List divideFiles(List fileList) { + Map> byName = fileList.stream().collect(Collectors.groupingBy(fileInfo -> { + String filename = fileInfo.string("FILE_NAME"); + return filename.substring(0, filename.lastIndexOf("_")); + })); + + return byName.values().stream() + .map(files -> { + DataObject result = new DataObject(); + DataObject metaInfo = null; + List imgs = null; + DataObject[] bgngAndEnd = null; + + DataObject first = files.get(0); + String groupType = first.string("FILE_GROUP_TYPE"); + + if ("TXT".equalsIgnoreCase(groupType)) { + Optional found = files.stream() + .filter(file -> "TXT".equalsIgnoreCase(file.string("FILE_EXTENSION"))) + .findFirst(); + boolean present = found.isPresent(); + imgs = !present ? files : new ArrayList<>(files); + if (present) { + imgs.remove(metaInfo = found.get()); + } + bgngAndEnd = getBgngDataAndEndData(imgs); + } else if ("JPG".equalsIgnoreCase(groupType)) { + bgngAndEnd = getBgngDataAndEndData(imgs = files); + metaInfo = bgngAndEnd[1] == null ? first : bgngAndEnd[1]; + } else if ("BIN".equalsIgnoreCase(groupType)) { + metaInfo = first; + imgs = new ArrayList<>(); + for (int i = 1, otherPhotoCnt = toInt(metaInfo.get("PHOTO_CNT")); i <= otherPhotoCnt; i++){ + String fileName = metaInfo.string("B64IMAGE" + i + "_NM"); + String b64str = metaInfo.string("B64IMAGE" + i); + DataObject dataObject = new DataObject() + .set("B64IMAGE_NM", fileName) + .set("B64IMAGE", b64str); + imgs.add(dataObject); + } + } + + result + .set("metaInfo", metaInfo) + .set("imageInfo", imgs) + .set("bgngData", bgngAndEnd[0]) + .set("endData", bgngAndEnd[1]) + .set("files", files); + if (metaInfo == null) + result.set("error", "metaInfo not found"); + + return result; + }) + .collect(Collectors.toCollection(ArrayList::new)); + } + + /**단속이미지정보 목록 내에서 최초단속자료와 최종단속자료를 반환한다. 단속일시 정보가 없을 경우 null을 반환한다.
+ * @param imageDataList 단속이미지정보 목록 + * @return 최초단속자료, 최종단속자료 + */ + private DataObject[] getBgngDataAndEndData(List imageDataList) { + DataObject[] bgngAndEnd = {null, null}; + + if (!isEmpty(imageDataList.get(0).get("CRDN_TIMESTAMP"))) { + DataObject bgngData = imageDataList.stream() + .min(Comparator.comparing(item -> new BigInteger(item.string("CRDN_TIMESTAMP")))) + .orElseThrow(); + + DataObject endData = imageDataList.stream() + .max(Comparator.comparing(item -> new BigInteger(item.string("CRDN_TIMESTAMP")))) + .orElseThrow(); + + bgngAndEnd[0] = bgngData; + bgngAndEnd[1] = endData; + } + + return bgngAndEnd; + } + + /**최초단속정보와 최종단속정보를 기준으로 단속대장의 최초단속시간과 최종단속시간을 설정한다.
+ * @param crdn 단속대장, bgngData 최초단속자료, endData 최종단속자료 + * @return + */ + private void crdnTimeRangeSet(Crdn crdn, DataObject bgngData, DataObject endData) { + if (isEmpty(bgngData) || isEmpty(endData)) return; + + String crdnBgngTm = endData.string("CRDN_BGNG_TM"); + if (!isEmpty(crdnBgngTm)) { + crdn.setCrdnBgngTm(crdnBgngTm); + crdn.setCrdnEndTm(endData.string("CRDN_END_TM")); + } else { + String crdnTm = endData.string("CRDN_TM"); + if (!isEmpty(crdnTm)){ + crdn.setCrdnBgngTm(bgngData.string("CRDN_TM")); + crdn.setCrdnEndTm(crdnTm); + } + } + } + + /**단속이미지정보를 List로 변환한다.
+ * @param imageList 단속이미지정보 목록, fileGroupType 연계파일그룹형식 + * @return fileInfo리스트 + */ + private List parseDataInfoToFileInfo(List imageList, String fileGroupType){ + try { + List fileInfos = null; + if ("JPG,TXT".contains(fileGroupType)) { + List files = imageList.stream() + .map(imageInfo -> { + File img = (File)imageInfo.get("file"); + return ifEmpty(img, new File(imageInfo.string("FILE_PATH"))); + }) + .toList(); + + fileInfos = new FileInfoFactory().createFileInfos(null, files); + for (int i = 0; i < fileInfos.size(); i++) { + FileInfo fileInfo = fileInfos.get(i); + fileInfo.setName("image" + i + "." + fileInfo.getExtension()); + } + } else if ("BIN".equals(fileGroupType)) { + fileInfos = new ArrayList<>(); + for (int i = 0; i < imageList.size(); i++){ + String fileName = imageList.get(i).string("B64IMAGE_NM"); + String b64str = imageList.get(i).string("B64IMAGE"); + FileInfo FileInfo = SingleFileParser.base64ToFileInfo(fileName, b64str, (i + 1)); + fileInfos.add(FileInfo); + } + } + return fileInfos; + } catch (Exception e) { + throw runtimeException(e); + } + }; +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java b/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java index 0049394c..a5684588 100644 --- a/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java +++ b/src/main/java/cokr/xit/fims/crdn/web/Crdn05Controller.java @@ -339,18 +339,22 @@ public class Crdn05Controller extends ApplicationController { .filter(linkFileInfo -> !linkFileInfo.equals("{}")) .map(linkFileInfo -> fromJson(linkFileInfo, DataObject.class)) .toList(); - Map resultMap = importService.createCrdnByEquipmentLinkFile(processInfo, linkFileInfoList); - boolean saved = (boolean) resultMap.get("saved"); + Map result = importService.createCrdnByEquipmentLinkFile(processInfo, linkFileInfoList); + return new ModelAndView("jsonView") + .addAllObjects(result); +/* + boolean saved = (boolean) result.get("saved"); ModelAndView mav = new ModelAndView("jsonView") .addObject("saved", saved); - if (!isEmpty(resultMap.get("alertMessage"))) - mav.addObject("alertMessage", resultMap.get("alertMessage")); + if (!isEmpty(result.get("alertMessage"))) + mav.addObject("alertMessage", result.get("alertMessage")); if (!saved) - mav.addObject("failReason", ifEmpty(resultMap.get("failReason"), () -> "알 수 없는 오류")); + mav.addObject("failReason", ifEmpty(result.get("failReason"), () -> "알 수 없는 오류")); return mav; +*/ } @RequestMapping(name="장비업체 단속파일로 단속자료 생성", value="/020/upload.do") @@ -431,14 +435,17 @@ public class Crdn05Controller extends ApplicationController { } nextTempGroupSeq = parser.getTempGroupSeq(); } - +/* if (parsed.isEmpty()) return new ModelAndView("jsonView") .addObject("saved", false) .addObject("alertMessage", "등록할 파일을 찾지 못했습니다") .addObject("failReason", "등록할 파일을 찾지 못했습니다"); - - Map resultMap = importService.createCrdnByEquipmentLinkFile(processInfo, parsed); +*/ + Map result = importService.createCrdnByEquipmentLinkFile(processInfo, parsed); + return new ModelAndView("jsonView") + .addAllObjects(result); +/* boolean saved = (boolean)resultMap.get("saved"); ModelAndView mav = new ModelAndView("jsonView") @@ -450,6 +457,7 @@ public class Crdn05Controller extends ApplicationController { mav.addObject("failReason", ifEmpty(resultMap.get("failReason"), () -> "알 수 없는 오류")); return mav; +*/ } /**단속자료 수기 등록 팝업화면을 반환한다. diff --git a/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java b/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java index 950e54bc..83c634ca 100644 --- a/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java +++ b/src/main/java/cokr/xit/fims/mngt/service/bean/TaskProcessor.java @@ -113,6 +113,77 @@ public class TaskProcessor extends AbstractBean { return "01"; } + public List getDuplicates(List crdns) { + if (isEmpty(crdns)) + return crdns; + + ArrayList copies = new ArrayList<>(crdns); + Map duplicates = crdnStngMapper.selectDuplicateCrdns(copies).stream().collect(Collectors.toMap( + info -> info.get("VHRNO") + "-" + info.get("CRDN_YMD"), + info -> info + )); + List found = copies.stream() + .filter(crdn -> { + String key = crdn.getVhrno() + "-" + crdn.getCrdnYmd(); + DataObject info = duplicates.get(key); + return info != null && toInt(info.get("CRDN_CNT")) > 0; + }) + .collect(Collectors.toCollection(ArrayList::new)); + copies.removeAll(found); + copies.stream().collect(Collectors.groupingBy( + crdn -> crdn.getVhrno() + "-" + crdn.getCrdnYmd()) + ).forEach((str, items) -> { + int size = items.size(); + if (size < 2) return; + + for (int i = 1; i < size; ++i) { + found.add(items.get(i)); + } + }); + + return found; + } + + public Map getExcluded(List crdns) { + List exemptedCrdns = getExemptedCrdns(crdns); + return exemptedCrdns.stream() + .collect(Collectors.toMap( + crdn -> crdn, + crdn -> { + boolean created = isEmpty(crdn.getCrdnId()), + exempted = exemptedCrdns.contains(crdn); + String status = crdn.getCrdnSttsCd(); + if (created) { + if ("83".equals(status)) // 계고, 계고 + return newLevyExcl(crdn, "2", "192"); + if (exempted) { + crdn.setCrdnSttsCd("81"); + return newLevyExcl(crdn, "1", "145"); // 비부과, 면제차량 + } else + return null; + } else { + if (!"81,83".contains(status) && exempted) + return newLevyExcl(crdn, "1", "145"); // 비부과, 면제차량 + + return null; + } + } + )); + } + + protected List getExemptedCrdns(List crdns) { + Map exempted = exmptnVhclMapper.selectExemptedCrdns(crdns).stream().collect(Collectors.toMap( + info -> info.get("VHRNO") + "-" + info.get("CRDN_YMD"), + info -> info + )); + return crdns.stream().filter(crdn -> { + String key = crdn.getVhrno() + "-" + crdn.getCrdnYmd(); + DataObject info = exempted.get(key); + return info != null; + }) + .collect(Collectors.toCollection(ArrayList::new)); + } + /**단속 정보의 상태에 따라 부과제외 정보를 생성한다. * @param crdn 단속 정보 * @return @@ -150,7 +221,7 @@ public class TaskProcessor extends AbstractBean { LevyExcl excl01 = new LevyExcl(); excl01.setCrdnId(crdn.getCrdnId()); excl01.setSggCd(crdn.getSggCd()); - excl01.setLevyExclYmd(dateFormats.dateFormat("yyyyMMdd").format(System.currentTimeMillis())); + excl01.setLevyExclYmd(dateFormats.today()); excl01.setLevyExclSeCd(exclSeCd); excl01.setLevyExclRsnCd(exclRsnCd); excl01.setEtcCn(""); diff --git a/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml b/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml index f7fec177..33a6f8c3 100644 --- a/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml +++ b/src/main/resources/sql/mapper/fims/crdn/crdn-inst-mapper.xml @@ -58,8 +58,8 @@ INSERT INTO TB_CRDN ( , DEL_DT , DLTR , DEL_RSN -) -SELECT #{crdnId} +) VALUES ( + #{crdnId} , #{sggCd} , #{crdnRegSeCd} , #{crdnInptSeCd} @@ -111,14 +111,7 @@ SELECT #{crdnId} , #{removedAt} , #{removedBy} , #{delRsn} - FROM DUAL -WHERE NOT EXISTS ( - SELECT * - FROM TB_CRDN - WHERE VHRNO = #{vhrno} - AND CRDN_YMD = #{crdnYmd} - ) - +) /* 단속 부가 정보 등록(crdnInstMapper.insertCrdnAddition) */ diff --git a/src/main/resources/sql/mapper/fims/crdn/crdn-stng-mapper.xml b/src/main/resources/sql/mapper/fims/crdn/crdn-stng-mapper.xml index c75d19e7..5335a589 100644 --- a/src/main/resources/sql/mapper/fims/crdn/crdn-stng-mapper.xml +++ b/src/main/resources/sql/mapper/fims/crdn/crdn-stng-mapper.xml @@ -2,9 +2,18 @@ + -/* 기본금액 조회(crdnStngMapper.selectBasicAmt) */ SELECT AMT FROM TB_AMT WHERE USE_YN = 'Y' @@ -21,8 +30,7 @@ SELECT AMT -/* 법정동코드 조회(crdnStngMapper.selectStdgNm) */ SELECT CONCAT(A.EMD_NM, CASE WHEN A.LI_NM = '' THEN '' @@ -32,8 +40,7 @@ SELECT CONCAT(A.EMD_NM, WHERE STDG_CD = #{stdgCd} -/* 법정동코드 목록 조회(crdnStngMapper.selectStdgNmList) */ SELECT CONCAT(A.EMD_NM, CASE WHEN A.LI_NM = '' THEN '' @@ -45,8 +52,7 @@ SELECT CONCAT(A.EMD_NM, ORDER BY A.EMD_NM, A.LI_NM -/* 법정동명으로 법정동코드 조회(crdnStngMapper.selectStdgCdListByStdgNm) */ SELECT STDG_CD FROM TB_STDG WHERE EMD_NM IS NOT NULL diff --git a/src/main/resources/sql/mapper/fims/crdn/exmptn-vhcl-mapper.xml b/src/main/resources/sql/mapper/fims/crdn/exmptn-vhcl-mapper.xml index 3ea98aca..7814162f 100644 --- a/src/main/resources/sql/mapper/fims/crdn/exmptn-vhcl-mapper.xml +++ b/src/main/resources/sql/mapper/fims/crdn/exmptn-vhcl-mapper.xml @@ -2,6 +2,17 @@ + +