package com.batch.config; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import com.batch.mapper.primary.MatchingInnerDelingMapper; import com.batch.util.StatisticsUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j @RequiredArgsConstructor public class MatchingExtraProcessorAuto { private final MatchingInnerDelingMapper matchingInnerDelingMapper; @SuppressWarnings({ "unchecked", "rawtypes" }) public long process(Map paramRec, int iCmbnOwnCnt, int iCmbnTranCnt, int iStartOwn, int iStartTran, long mtchNumber) throws Exception { // Job Create Log UUID uuid = UUID.randomUUID(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss"); String sDate = dateFormat.format(new Date()) + ":" + uuid.toString(); Map paramLog = new HashMap(); paramLog.put("user_job_id", sDate); paramLog.put("user_job_name", "자동조합매칭(" + paramRec.toString() + ",[" + iCmbnOwnCnt + "," + iStartOwn + "],[" + iCmbnTranCnt + "," + iStartTran + "])"); matchingInnerDelingMapper.createUserJob(paramLog); int iUpdated = 0; String sSysSe = (String) paramRec.get("sys_se"); String sAccnutYm = (String) paramRec.get("accnut_ym"); String sCprCode = (String) paramRec.get("cpr_code"); String sPartCpr = (String) paramRec.get("partn_cpr"); String sDelngCrncy = (String) paramRec.get("delng_crncy"); String sConds = (String) paramRec.get("conds"); // 작업시작 Map mParam = new HashMap(); mParam.put("sysSe", sSysSe); mParam.put("accnutYm", sAccnutYm); mParam.put("conds", sConds); mParam.put("delngCrncy", sDelngCrncy); // ---------------------------------------------------------------------------- // 자기법인 데이타 가져오기 mParam.put("cprCode", sCprCode); mParam.put("partnCpr", sPartCpr); List lMatchingDataOne = matchingInnerDelingMapper.getMatchingExtraDataOne(mParam); // 상대법인 데이타 가져오기 mParam.put("cprCode", sPartCpr); mParam.put("partnCpr", sCprCode); List lMatchingDataTwo = matchingInnerDelingMapper.getMatchingExtraDataTwo(mParam); // Combination 데이타 만들기 List compResult = new ArrayList(); List> llMatchingDataOne = new ArrayList>(); List> llMatchingDataTwo = new ArrayList>(); int iEndOwn = lMatchingDataOne.size(); if (iCmbnOwnCnt == 2) { iEndOwn = iStartOwn + 1000; if (iEndOwn > lMatchingDataOne.size()) iEndOwn = lMatchingDataOne.size(); } if (iCmbnOwnCnt == 3) { iEndOwn = iStartOwn + 50; if (iEndOwn > lMatchingDataOne.size()) iEndOwn = lMatchingDataOne.size(); } if (iCmbnOwnCnt > 3) { iEndOwn = iStartOwn + 25; if (iEndOwn > lMatchingDataOne.size()) iEndOwn = lMatchingDataOne.size(); } int iEndTran = lMatchingDataTwo.size(); if (iCmbnTranCnt == 2) { iEndTran = iStartTran + 1000; if (iEndTran > lMatchingDataTwo.size()) iEndTran = lMatchingDataTwo.size(); } if (iCmbnTranCnt == 3) { iEndTran = iStartTran + 50; if (iEndTran > lMatchingDataTwo.size()) iEndTran = lMatchingDataTwo.size(); } if (iCmbnTranCnt > 3) { iEndTran = iStartTran + 25; if (iEndTran > lMatchingDataTwo.size()) iEndTran = lMatchingDataTwo.size(); } StatisticsUtil.reculsion(lMatchingDataOne, compResult, iStartOwn, iEndOwn, iCmbnOwnCnt, llMatchingDataOne); StatisticsUtil.reculsion(lMatchingDataTwo, compResult, iStartTran, iEndTran, iCmbnTranCnt, llMatchingDataTwo); // ---------------------------------------------------------------------------- // 자기법인 데이타를 맵으로 처리한다. Map>> mMatchingDataOne = new HashMap>>(); for (List curlMap : llMatchingDataOne) { BigDecimal bdKey = BigDecimal.ZERO; for (Map curMap : curlMap) { bdKey = bdKey.add((BigDecimal) curMap.get("delng_amt")); } List> curllMap = new ArrayList>(); if (mMatchingDataOne.containsKey(bdKey)) curllMap = mMatchingDataOne.get(bdKey); curllMap.add(curlMap); mMatchingDataOne.put(bdKey, curllMap); } // 상대법인 데이타를 맵으로 처리한다. Map>> mMatchingDataTwo = new HashMap>>(); for (List curlMap : llMatchingDataTwo) { BigDecimal bdKey = BigDecimal.ZERO; for (Map curMap : curlMap) { bdKey = bdKey.add((BigDecimal) curMap.get("delng_amt")); } List> curllMap = new ArrayList>(); if (mMatchingDataTwo.containsKey(bdKey)) curllMap = mMatchingDataTwo.get(bdKey); curllMap.add(curlMap); mMatchingDataTwo.put(bdKey, curllMap); } // 여기서 매칭 비교 // 비교 lMatchingDataOne vs mMatchingDataTwo List lMatchingResultUpdate = new ArrayList(); // 업데이트할 대상 String mtchSys = "AUTO"; String mtchType = "EX_" + iCmbnOwnCnt + "_" + iCmbnTranCnt; String mtchTypeName = "자기(" + iCmbnOwnCnt + "건Sum), 상대(" + iCmbnTranCnt + "건Sum), (" + sDelngCrncy + "), 비교(금액)"; for (BigDecimal curKey : mMatchingDataOne.keySet()) { if (mMatchingDataTwo.containsKey(curKey)) { List> llMapOne = mMatchingDataOne.get(curKey); List> llMapTwo = mMatchingDataTwo.get(curKey); // 위와 관련된 동일 레코드가 있는 리스트 삭제 for (int i = llMapOne.size() - 1; i >= 0; i--) { List curlMap = llMapOne.get(i); for (Map curMap : lMatchingResultUpdate) { int curIdx = curlMap.indexOf(curMap); if (curIdx != -1) { llMapOne.remove(i); break; } } } for (int i = llMapTwo.size() - 1; i >= 0; i--) { List curlMap = llMapTwo.get(i); for (Map curMap : lMatchingResultUpdate) { int curIdx = curlMap.indexOf(curMap); if (curIdx != -1) { llMapTwo.remove(i); break; } } } int iMin = Math.min(llMapOne.size(), llMapTwo.size()); if (iMin > 0) { mtchNumber++; } while (iMin > 0) { List curlMapOne = llMapOne.get(0); for (Map curMap : curlMapOne) { curMap.put("mtch_sys", mtchSys); curMap.put("mtch_ty", mtchType); curMap.put("mtch_ty_nm", mtchTypeName); curMap.put("mtch_ky", mtchNumber); lMatchingResultUpdate.add(curMap); } llMapOne.remove(0); List curlMapTwo = llMapTwo.get(0); for (Map curMap : curlMapTwo) { curMap.put("mtch_sys", mtchSys); curMap.put("mtch_ty", mtchType); curMap.put("mtch_ty_nm", mtchTypeName); curMap.put("mtch_ky", mtchNumber); lMatchingResultUpdate.add(curMap); } llMapTwo.remove(0); // 위와 관련된 동일 레코드가 있는 리스트 삭제(추가 업데이트 목록) for (int i = llMapOne.size() - 1; i >= 0; i--) { List curlMap = llMapOne.get(i); for (Map curMap : curlMapOne) { int curIdx = curlMap.indexOf(curMap); if (curIdx != -1) { llMapOne.remove(i); break; } } } for (int i = llMapTwo.size() - 1; i >= 0; i--) { List curlMap = llMapTwo.get(i); for (Map curMap : curlMapTwo) { int curIdx = curlMap.indexOf(curMap); if (curIdx != -1) { llMapTwo.remove(i); break; } } } iMin = Math.min(llMapOne.size(), llMapTwo.size()); } } } // ---------------------------------------------------------------------------- // 여기서 결과 업데이트 iUpdated = 0; int limit = 1000; // 1000건씩 batch List lUpdated = new ArrayList(); for (Map curMap : lMatchingResultUpdate) { lUpdated.add(curMap); if (lUpdated.size() == limit) { matchingInnerDelingMapper.setExtraResult(Map.of("itemList", lUpdated)); iUpdated = iUpdated + lUpdated.size(); lUpdated.clear(); } } if (lUpdated.size() > 0) { matchingInnerDelingMapper.setExtraResult(Map.of("itemList", lUpdated)); iUpdated = iUpdated + lUpdated.size(); } log.debug("Updated OrgData : " + iUpdated + "건"); // 작업종료에 대한 로그 업데이트 paramLog.put("exit_code", "0"); paramLog.put("exit_message", ""); matchingInnerDelingMapper.finishUserJob(paramLog); return mtchNumber; } }