diff --git a/src/main/java/cokr/xit/adds/biz/nims/dao/BizNimsMapper.java b/src/main/java/cokr/xit/adds/biz/nims/dao/BizNimsMapper.java index da7b0ba..c135721 100644 --- a/src/main/java/cokr/xit/adds/biz/nims/dao/BizNimsMapper.java +++ b/src/main/java/cokr/xit/adds/biz/nims/dao/BizNimsMapper.java @@ -1,21 +1,16 @@ package cokr.xit.adds.biz.nims.dao; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; -import org.egovframe.rte.psl.dataaccess.mapper.Mapper; +import org.egovframe.rte.psl.dataaccess.mapper.*; -import cokr.xit.adds.biz.nims.model.BizNimsDto; -import cokr.xit.adds.biz.nims.model.BizNimsRequest; -import cokr.xit.adds.biz.nims.model.BizNimsResponse; -import cokr.xit.adds.inf.nims.model.NimsApiDto; -import cokr.xit.adds.inf.nims.model.NimsApiRequest; -import cokr.xit.foundation.component.AbstractMapper; +import cokr.xit.adds.biz.nims.model.*; +import cokr.xit.adds.inf.nims.model.*; +import cokr.xit.foundation.component.*; /** *
- * description : 
+ * description :
  *
  * packageName : cokr.xit.adds.inf.nims.dao
  * fileName    : InfNimsMapper
@@ -36,7 +31,7 @@ public interface BizNimsMapper extends AbstractMapper {
 	void mergeBsshInfoSt(final NimsApiDto.BsshInfoSt dto);
 	List selectBsshInfos(final NimsApiRequest.BsshInfoReq dto);
 
-	void mergeProductInfoKd(final NimsApiDto.ProductInfoKd dto);
+	 void mergeProductInfoKd(final T t);
 	List selectProductInfos(final NimsApiRequest.ProductInfoReq dto);
 
 	void mergeJurisdictionGovInfo(NimsApiDto.JurisdictionGovInfo dto);
@@ -49,6 +44,9 @@ public interface BizNimsMapper extends AbstractMapper {
 
 	int insertDsuseMgtReceipt(final BizNimsRequest.DsuseMgtReceiptReq dto);
 	int updateDsuseMgtReceipt(final BizNimsRequest.DsuseMgtReceiptReq dto);
+
+	Optional selectCheckDsuseLocBydscdmngId(final String dscdmngId);
+	void updateDsuseLocOfDsuseMgt(final BizNimsRequest.DsuseMgtRsltReq dto);
 	int updateDsuseMgtRslt(final BizNimsRequest.DsuseMgtRsltReq dto);
 
 	int insertDsuseMgtDtl(final BizNimsDto.DsuseMgtDtl dto);
diff --git a/src/main/java/cokr/xit/adds/biz/nims/service/BizNimsService.java b/src/main/java/cokr/xit/adds/biz/nims/service/BizNimsService.java
index af4aaeb..137f626 100644
--- a/src/main/java/cokr/xit/adds/biz/nims/service/BizNimsService.java
+++ b/src/main/java/cokr/xit/adds/biz/nims/service/BizNimsService.java
@@ -31,10 +31,11 @@ public interface BizNimsService {
 	// NIMS API CALL
 	//------------------------------------------------------------------------------------------------------
 	ApiBaseResponse> getBsshInfoSt(final NimsApiRequest.BsshInfoReq reqDto);
-	List saveBsshInfoSt(final NimsApiRequest.BsshInfoReq dto);
-	List saveProductInfoKd(final NimsApiRequest.ProductInfoReq dto, boolean isMnfSeqInfo);
+	List saveBsshInfoStQueryBsshInfoByBsshCd(final NimsApiRequest.BsshInfoReq dto);
+	ApiBaseResponse> getProductInfoKd(final NimsApiRequest.ProductInfoReq dto, boolean isMnfSeqInfo);
+	List saveProductInfoKdQueryProductByProductId(final NimsApiRequest.ProductInfoReq dto, boolean isMnfSeqInfo);
 	ApiBaseResponse> getMnfSeqInfo(final NimsApiRequest.MnfSeqInfoReq dto);
-	List getMnfSeqInfo2(final NimsApiRequest.MnfSeqInfoReq dto);
+//	List getMnfSeqInfo2(final NimsApiRequest.MnfSeqInfoReq dto);
 	List getJurisdictionGovInfo(final NimsApiRequest.JurisdictionGovInfoReq dto);
 	List getNimsDsuseRptInfo(final NimsApiRequest.DsuseRptInfoReq dto);
 
@@ -42,7 +43,7 @@ public interface BizNimsService {
 	//------------------------------------------------------------------------------------------------------
 	// NIMS BIZ
 	//------------------------------------------------------------------------------------------------------
-	BizNimsRequest.DsuseMgtReceiptReq saveDsuseMgtReceipt(final BizNimsRequest.DsuseMgtReceiptReq dto, final List dtls, List files);
+	BizNimsRequest.DsuseMgtReceiptReq saveDsuseMgtReceipt(final BizNimsRequest.DsuseMgtReceiptReq reqDto, final List dtls, final List files, final NimsApiDto.BsshInfoSt bsshInfoSt, final List prdList);
 
 	BizNimsRequest.DsuseMgtReceiptReq modifyDsuseMgtReceiptMstInfo(final BizNimsRequest.DsuseMgtReceiptReq reqDto);
 
diff --git a/src/main/java/cokr/xit/adds/biz/nims/service/bean/BizNimsServiceBean.java b/src/main/java/cokr/xit/adds/biz/nims/service/bean/BizNimsServiceBean.java
index 99bad34..813f6b2 100644
--- a/src/main/java/cokr/xit/adds/biz/nims/service/bean/BizNimsServiceBean.java
+++ b/src/main/java/cokr/xit/adds/biz/nims/service/bean/BizNimsServiceBean.java
@@ -1,41 +1,32 @@
 package cokr.xit.adds.biz.nims.service.bean;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.validation.Validation;
-import javax.validation.Validator;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.web.multipart.MultipartFile;
-
-import cokr.xit.adds.biz.nims.dao.BizNimsMapper;
-import cokr.xit.adds.biz.nims.model.BizNimsDto;
-import cokr.xit.adds.biz.nims.model.BizNimsRequest;
-import cokr.xit.adds.biz.nims.model.BizNimsResponse;
-import cokr.xit.adds.biz.nims.service.BizNimsService;
-import cokr.xit.adds.core.Constants;
-import cokr.xit.adds.core.Constants.RPT_TY_CD;
-import cokr.xit.adds.core.model.ApiBaseResponse;
-import cokr.xit.adds.core.spring.exception.ApiCustomException;
-import cokr.xit.adds.core.util.ApiUtil;
-import cokr.xit.adds.inf.nims.model.NimsApiDto;
-import cokr.xit.adds.inf.nims.model.NimsApiDto.BsshInfoSt;
-import cokr.xit.adds.inf.nims.model.NimsApiRequest;
-import cokr.xit.adds.inf.nims.model.NimsApiRequest.BsshInfoReq;
-import cokr.xit.adds.inf.nims.model.NimsApiResult;
-import cokr.xit.adds.inf.nims.service.InfNimsService;
-import cokr.xit.base.file.FileInfo;
-import cokr.xit.base.file.service.FileService;
-import cokr.xit.base.file.web.FileInfoFactory;
-import cokr.xit.foundation.component.AbstractServiceBean;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
+import java.util.*;
+import java.util.concurrent.*;
+
+import javax.validation.*;
+
+import org.apache.commons.lang3.*;
+import org.springframework.stereotype.*;
+import org.springframework.web.multipart.*;
+
+import cokr.xit.adds.biz.nims.dao.*;
+import cokr.xit.adds.biz.nims.model.*;
+import cokr.xit.adds.biz.nims.service.*;
+import cokr.xit.adds.core.*;
+import cokr.xit.adds.core.Constants.*;
+import cokr.xit.adds.core.model.*;
+import cokr.xit.adds.core.spring.exception.*;
+import cokr.xit.adds.core.util.*;
+import cokr.xit.adds.inf.nims.model.*;
+import cokr.xit.adds.inf.nims.model.NimsApiDto.*;
+import cokr.xit.adds.inf.nims.model.NimsApiRequest.*;
+import cokr.xit.adds.inf.nims.service.*;
+import cokr.xit.base.file.*;
+import cokr.xit.base.file.service.*;
+import cokr.xit.base.file.web.*;
+import cokr.xit.foundation.component.*;
+import lombok.*;
+import lombok.extern.slf4j.*;
 
 /**
  * 
@@ -58,997 +49,980 @@ import lombok.extern.slf4j.Slf4j;
 public class BizNimsServiceBean extends AbstractServiceBean implements BizNimsService {
 
     private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
-	private final InfNimsService infNimsService;
-	private final BizNimsMapper bizNimsMapper;
-	private final FileService fileService;
-
-	//------------------------------------------------------------------------------------------------------
-	// NIMS API CALL
-	//------------------------------------------------------------------------------------------------------
-	@Override
-	public ApiBaseResponse> getBsshInfoSt(BsshInfoReq reqDto) {
-		if(isEmpty(reqDto.getBc()) && isEmpty(reqDto.getBi()) && isEmpty(reqDto.getBn())){
-			throw ApiCustomException.create("업체[사업자] 번호 또는 명, 사업자등록번호 중 하나는 필수 입니다");
-		}
-		if(!isEmpty(reqDto.getBn()) && reqDto.getBn().length() < 3) {
-			throw ApiCustomException.create("업체[사업자]명은 3자 이상 으로 조회해 주세요");
-		}
-
-		// DB 조회
-		List list = new ArrayList<>();
-		if("N".equals(reqDto.getDbSkipYn())) {
-			list = bizNimsMapper.selectBsshInfos(reqDto);
-			if (!isEmpty(list)){
-				//return list;
-				ApiBaseResponse> res = ApiBaseResponse.of(list);
-				res.setTotalCount(list.size());
-				return res;
-			}
-		}
-
-		if(isEmpty(reqDto.getK())){
-			reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey"));
-		}
-		reqDto.setFg("1");	// 조회범위(1-전체,2-내거래처)
-		//reqDto.setPg("1");  // 조회페이지
-		reqDto.setFg2("1"); // 조회범위2(1:NK(취급승인)포함 - default, 2:NK(취급승인)제외)
-
-		boolean isRprsntvNm = !isEmpty(reqDto.getRprsntvNm());//while(true) {
-
-		// 마약류취급자식별번호로 마약류취급자정보 조회
-		NimsApiResult.Response rslt = infNimsService.getBsshInfoSt(reqDto);
-		List curList = rslt.getResult();
-
-		for (BsshInfoSt d : curList) {
-			if(isEmpty(d.getBsshCd()))	continue;
-			d.setRgtr(reqDto.getUserId());
-			bizNimsMapper.mergeBsshInfoSt(d);
-			// 대표자 검색조건이 있는 경우
-			if (isRprsntvNm && !isEmpty(d.getRprsntvNm()) && d.getRprsntvNm().contains(reqDto.getRprsntvNm())) {
-				list.add(d);
-			}
-		}
-		if (!isRprsntvNm){
-			list.addAll(curList);
-		}
-
-		ApiBaseResponse> res = ApiBaseResponse.of(list);
-		res.setTotalCount(list.size());
-		return res;
-	}
-
-
-	/**
-	 * 
-	 *     DB에서 먼저 조회(dbSkipYn = 'Y' 인 경우는 DB 조회 skip)
-	 *     -> 조회 결과가 없는 경우 API 조회
-	 *     업체정보 조회후 DB 저장
-	 *     조회 건수를 제한하기 위해 조회 조건 강제 - 업체명(3자 이상) 필수
-	 * @param reqDto NimsApiRequest.BsshInfoRequest
-	 * @return List
-	 * 
- */ - @Override - public List saveBsshInfoSt(BsshInfoReq reqDto) { - if(isEmpty(reqDto.getBc()) && isEmpty(reqDto.getBi()) && isEmpty(reqDto.getBn())){ - throw ApiCustomException.create("업체[사업자] 번호 또는 명, 사업자등록번호 중 하나는 필수 입니다"); - } - if(!isEmpty(reqDto.getBn()) && reqDto.getBn().length() < 3) { - throw ApiCustomException.create("업체[사업자]명은 3자 이상 으로 조회해 주세요"); - } - - // DB 조회 - List list = new ArrayList<>(); - if("N".equals(reqDto.getDbSkipYn())) { - list = bizNimsMapper.selectBsshInfos(reqDto); - if (!isEmpty(list)) return list; - } - - if(isEmpty(reqDto.getK())){ - reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); - } - reqDto.setFg("1"); // 조회범위(1-전체,2-내거래처) - reqDto.setPg("1"); // 조회페이지 - reqDto.setFg2("1"); // 조회범위2(1:NK(취급승인)포함 - default, 2:NK(취급승인)제외) - - boolean isRprsntvNm = !isEmpty(reqDto.getRprsntvNm()); - while(true) { - // 마약류취급자식별번호로 마약류취급자정보 조회 - NimsApiResult.Response rslt = infNimsService.getBsshInfoSt(reqDto); - List curList = rslt.getResult(); - - if (isEmpty(curList)) - break; - - for (BsshInfoSt d : curList) { - if(isEmpty(d.getBsshCd())) continue; - d.setRgtr(reqDto.getUserId()); - bizNimsMapper.mergeBsshInfoSt(d); - // 대표자 검색조건이 있는 경우 - if (isRprsntvNm && !isEmpty(d.getRprsntvNm()) && d.getRprsntvNm().contains(reqDto.getRprsntvNm())) { - list.add(d); - } - } - if (!isRprsntvNm){ - list.addAll(curList); - } - - if(rslt.isEndYn()) break; - reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); - } - return list; - } - - /** - *
-	 *     DB에서 먼저 조회(dbSkipYn = 'Y' 인 경우는 DB 조회 skip)
-	 *     -> 조회 결과가 없는 경우 API 조회
-	 *     상품정보 조회후 DB 저장
-	 *     제조번호 조회 여부에 따라 제조번호, 일련번호, 유효기간 정보 목록 추가
-	 *     조회 건수를 제한하기 위해 조회 조건 강제 - 상품번호 또는 상품명(2자 이상) 필수
-	 * @param reqDto NimsApiRequest.ProductInfoRequest
-	 * @param isMnfSeqInfo 제조번호 조회 여부
-	 * @return
-	 * 
- */ - @Override - public List saveProductInfoKd(NimsApiRequest.ProductInfoReq reqDto, boolean isMnfSeqInfo) { - if(isEmpty(reqDto.getP()) && isEmpty(reqDto.getPn())){ - throw ApiCustomException.create("상품번호 또는 상품명중 하나는 필수 입니다"); - } - - if(!isEmpty(reqDto.getPn()) && reqDto.getPn().length() < 2){ - throw ApiCustomException.create("상품명은 2자 이상 으로 조회해 주세요"); - } - - List list = new ArrayList<>(); - - // DB 조회 - if("N".equals(reqDto.getDbSkipYn())) { - list = bizNimsMapper.selectProductInfos(reqDto); - if (!isEmpty(list)){ - if(isMnfSeqInfo){ - if(isEmpty(reqDto.getK())){ - productInfoaddMnfSeqs(list, getApiInfInfo(reqDto.getUserId()).get("apiKey")); - }else { - productInfoaddMnfSeqs(list, reqDto.getK()); - } - } - return list; - } - } - - if(isEmpty(reqDto.getK())){ - reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); - } - reqDto.setFg("1"); // 조회범위(1-전체,2-내거래처품목,3-청구코드매핑) - reqDto.setPg("1"); // 조회페이지 - reqDto.setFg2(""); // 중점일반구분(all, 1:중점, 2:일반) - - while(true) { - // 제품코드로 제품정보 조회 - NimsApiResult.Response rslt = infNimsService.getProductInfoKd(reqDto); - List curList = rslt.getResult(); - - if(isEmpty(curList)) break; - - for (NimsApiDto.ProductInfoKd d : curList) { - d.setRgtr(reqDto.getUserId()); - bizNimsMapper.mergeProductInfoKd(d); - } - - // 제조 번호, 일련번호, 유효기간 정보 목록 추가 - if(isMnfSeqInfo) productInfoaddMnfSeqs(curList, reqDto.getK()); - list.addAll(curList); - - if(rslt.isEndYn()) break; - reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); - } - return list; - } - - @Override - public ApiBaseResponse> getMnfSeqInfo(NimsApiRequest.MnfSeqInfoReq reqDto) { - if(isEmpty(reqDto.getK())){ - reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); - } - //reqDto.setFg("1"); // 제조번호 또는 일련번호 구분(1-제조번호, 2-일련번호, 3-바코드/RFID) - //reqDto.setPg("1"); // 조회페이지 - - // 시리얼번호 및 제조번호 기준 검색후, 결과내에서 유효기간으로 필터링 하도록 처리 - boolean isPrdValidDe = !isEmpty(reqDto.getT()) && !isEmpty(reqDto.getPrdValidDe()); - List list = new ArrayList<>(); - //while (true) { - NimsApiResult.Response rslt = infNimsService.getMnfSeqInfo(reqDto); - - List curList = rslt.getResult(); - - if(isPrdValidDe) { - for (NimsApiDto.MnfSeqInfo d : curList) { - if(!isEmpty(d.getPrdValidDe()) && d.getPrdValidDe().contains(reqDto.getPrdValidDe())){ - list.add(d); - } - } - }else { - list.addAll(curList); - } - - list.sort((a, b) -> { - if (isEmpty(a.getPrdValidDe()) && isEmpty(b.getPrdValidDe())) - return 0; - if (isEmpty(a.getPrdValidDe())) - return -1; - if (isEmpty(b.getPrdValidDe())) - return 1; - return a.getPrdValidDe().compareTo(b.getPrdValidDe()); - }); - - ApiBaseResponse> res = ApiBaseResponse.of(list); - res.setTotalCount(rslt.getBody().getTotalCount()); - return res; - } - - @Override - public List getMnfSeqInfo2(NimsApiRequest.MnfSeqInfoReq reqDto) { - if(isEmpty(reqDto.getK())){ - reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); - } - //reqDto.setFg("1"); // 제조번호 또는 일련번호 구분(1-제조번호, 2-일련번호, 3-바코드/RFID) - reqDto.setPg("1"); // 조회페이지 - - // 시리얼번호 및 제조번호 기준 검색후, 결과내에서 유효기간으로 필터링 하도록 처리 - boolean isPrdValidDe = !isEmpty(reqDto.getT()) && !isEmpty(reqDto.getPrdValidDe()); - List list = new ArrayList<>(); - while (true) { - NimsApiResult.Response rslt = infNimsService.getMnfSeqInfo(reqDto); - - List curList = rslt.getResult(); - - if (isEmpty(curList)) break; - - if(isPrdValidDe) { - for (NimsApiDto.MnfSeqInfo d : curList) { - if(!isEmpty(d.getPrdValidDe()) && d.getPrdValidDe().contains(reqDto.getPrdValidDe())){ - list.add(d); - } - } - }else { - list.addAll(curList); - // 올림 차순 정렬 - list.sort((a, b) -> { - if (isEmpty(a.getPrdValidDe()) && isEmpty(b.getPrdValidDe())) - return 0; - if (isEmpty(a.getPrdValidDe())) - return -1; - if (isEmpty(b.getPrdValidDe())) - return 1; - return a.getPrdValidDe().compareTo(b.getPrdValidDe()); - }); - } - // 데이타 조회 결과 마지막 페이지 이거나 100건 이상인 경우 종료 - if(rslt.isEndYn() || list.size() > 100 || isPrdValidDe) break; - - reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); - } - return list; - } - - @Override - public List getJurisdictionGovInfo(final NimsApiRequest.JurisdictionGovInfoReq reqDto) { - List list = new ArrayList<>(); - - // DB 조회 : 주소검색이면 DB 조회 skip - if("N".equals(reqDto.getDbSkipYn()) && isEmpty(reqDto.getAdr())) { - list = bizNimsMapper.selectJurisdictionGovInfos(reqDto); - if (!isEmpty(list)){ - return list; - } - } - - reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); - while(true) { - // 기관정보 조회 - NimsApiResult.Response rslt = infNimsService.getJurisdictionGovInfo(reqDto); - List curList = rslt.getResult(); - - if(isEmpty(curList)) break; - for(NimsApiDto.JurisdictionGovInfo d : curList) { - d.setRgtr(reqDto.getUserId()); - bizNimsMapper.mergeJurisdictionGovInfo(d); - } - list.addAll(curList); - - if(rslt.isEndYn()) break; - reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); - } - return list; - } - - @Override - public List getNimsDsuseRptInfo(NimsApiRequest.DsuseRptInfoReq reqDto) { - reqDto.setFg("2"); // 조회기준일자(1-보고일,2-취급일) - reqDto.setPg("1"); // 조회 페이지 - reqDto.setSe("AAR"); // 보고구분코드 - 폐기 - - Map apiInfInfo = getApiInfInfo(reqDto.getUserId()); - reqDto.setK(apiInfInfo.get("apiKey")); - reqDto.setGc(apiInfInfo.get("deptCd")); // 관할관청코드 - ApiUtil.validate(reqDto, null, validator); - - List rtnList = findNimsDsuseRptsOfApi(reqDto, false); - - rtnList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); - return rtnList; - } - //------------------------------------------------------------------------------------------------------ - // NIMS BIZ - //------------------------------------------------------------------------------------------------------ - /** - *
-	 * 사고마약류폐기 신청 접수
-	 * @param reqDto BizNimsRequest.DsuseMgtReceipt
-	 * @return BizNimsRequest.DsuseMgtReceipt 생성된 폐기관리 정보
-	 * 
- */ - @Override - public BizNimsRequest.DsuseMgtReceiptReq saveDsuseMgtReceipt(final BizNimsRequest.DsuseMgtReceiptReq reqDto, final List dtls, final List files) { - ApiUtil.validate(reqDto, null, validator); - if(reqDto.getRndDtlRptCnt() != dtls.size()) throw ApiCustomException.create("폐기물 보고수 오류[폐기물 갯수 확인]"); - ApiUtil.validate(dtls, null, validator); - reqDto.setRgtr(reqDto.getUserId()); - - if(files.size() != dtls.size()) throw ApiCustomException.create("폐기물 파일 갯수 오류[파일 갯수 확인]"); - - if(isEmpty(reqDto.getDscdmngId())) { - - if (bizNimsMapper.insertDsuseMgtReceipt(reqDto) == 1) { - - // 폐기관리 상세 등록 - saveDsuseMgtDtls(reqDto, dtls, files); - } else { - throw ApiCustomException.create("폐기 관리 마스터 등록 실패"); - } - } else { - bizNimsMapper.updateDsuseMgtReceipt(reqDto); - - // 파일 삭제 - String[] fileIds = bizNimsMapper.selectFileId( - Map.of("infType", Constants.FILE_INF_TYPE.DSUSE_PRD_IMG.getCode(), "infKey", reqDto.getDscdmngId())); - if (fileIds.length > 0) { - fileService.delete(fileIds); - - } - // 폐기관리 상세 삭제 - bizNimsMapper.deleteDsuseMgtDtl(reqDto.getDscdmngId()); - - // 폐기관리 상세 등록 - saveDsuseMgtDtls(reqDto, dtls, files); - } - return reqDto; - } - - @Override - public BizNimsRequest.DsuseMgtReceiptReq modifyDsuseMgtReceiptMstInfo(BizNimsRequest.DsuseMgtReceiptReq reqDto) { - bizNimsMapper.updateDsuseMgtReceipt(reqDto); - return reqDto; - } - - /** - *
-	 * 사고마약류폐기 통보[결과]처리
-	 * @param reqDto BizNimsRequest.DsuseMgtRslt
-	 * @return BizNimsRequest.DsuseMgtRslt 생성된 폐기관리 정보
-	 * 
- */ - public BizNimsRequest.DsuseMgtRsltReq saveDsuseMgtRslt(final BizNimsRequest.DsuseMgtRsltReq reqDto, final List files, final String fileChangeYn) { - ApiUtil.validate(reqDto, null, validator); - reqDto.setRgtr(reqDto.getUserId()); - - if(bizNimsMapper.updateDsuseMgtRslt(reqDto) == 1){ - if("Y".equals(fileChangeYn)) { - Map map = Map.of("infType", Constants.FILE_INF_TYPE.DSUSE_IMG.getCode(), "infKey", reqDto.getDscdmngId()); - // 파일 삭제 - String[] fileIds = bizNimsMapper.selectFileId(map); - if (fileIds.length > 0) { - fileService.delete(fileIds); - } - // DB 파일 정보 삭제 - bizNimsMapper.deleteFileInfo(map); - - if(files != null) { - int idx = 1; - for (MultipartFile mf : files) { - uploadFileSave(Constants.FILE_INF_TYPE.DSUSE_IMG.getCode(), reqDto.getDscdmngId(), - String.valueOf(idx), mf); - idx++; - } - } - - } - - } else { - throw ApiCustomException.create("폐기 관리 정보 변경[통보(결과) 처리] 실패"); - } - return reqDto; - } - - /** - *
-	 * 사고 마약류 폐기 관리 목록 조회
-	 * 1. 사고마약류 폐기관리 목록 조회
-	 * 2. 사고마약류 결과결과[통보]서, 폐기내역 및 사진 문서 작성을 위한 데이타 조회
-	 * @param reqDto BizNimsRequest.DsuseMgtInq
-	 * @param isForDoc true: 문서작성용, false: 조회용
-	 * @return List 조회된 폐기 관리 목록
-	 * 
- */ - @Override - public List getDsuseMgts(final BizNimsRequest.DsuseMgtInqReq reqDto, final boolean isForDoc) { - List resList = bizNimsMapper.selectDsuseMgts(reqDto); - String apiKey = null; - if(isForDoc) apiKey = getApiInfInfo(reqDto.getUserId()).get("apiKey"); - - for (BizNimsResponse.DsuseMgtRes dto : resList) { - dto.setRptTyNm(RPT_TY_CD.getName(dto.getRptTyCd())); - dto.setDsuseSeNm(Constants.DSUSE_SE_CD.getName(dto.getDsuseSeCd())); - dto.setDsusePrvNm(Constants.DSUSE_PRV_CD.getName(dto.getDsusePrvCd())); - dto.setDsuseMthNm(Constants.DSUSE_MTH_CD.getName(dto.getDsuseMthCd())); - - Map map = new HashMap<>(); - map.put("dscdmngId", dto.getDscdmngId()); - List dsuseRptInfoDtls = bizNimsMapper.selectDsuseMgtDtls(map); - if(isForDoc) setDsuseMgtDtlAddProductInfo(dsuseRptInfoDtls, reqDto.getUserId(), apiKey); - dto.getDsuseMgtDtls().addAll(dsuseRptInfoDtls); - } - - return resList; - } - - @Override - public List saveDsuseRptInfo(NimsApiRequest.DsuseRptInfoReq reqDto) { - reqDto.setFg("2"); // 조회기준일자(1-보고일,2-취급일) - reqDto.setPg("1"); // 조회 페이지 - reqDto.setSe("AAR"); // 보고구분코드 - 폐기 - - Map apiInfInfo = getApiInfInfo(reqDto.getUserId()); - reqDto.setK(apiInfInfo.get("apiKey")); - reqDto.setGc(apiInfInfo.get("deptCd")); // 관할관청코드 - ApiUtil.validate(reqDto, null, validator); - - List rtnList = saveFromfindDsuseRptDataByNimsApi(reqDto); - - rtnList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); - return rtnList; - } - - /** - *
-	 * saveDsuseRptInfo 대체 메소드 - 확인후 적용
-
-	 * 6. return List에 현재 데이타 추가 - 변경인 경우만 추가
-	 * 8. 결과 sort 및 return
-	 * @param reqDto
-	 * @return
-	 * 
- */ - @Override - public List getDsuseRptAndDsuseMgtMapping(BizNimsRequest.DsuseRptMappingInqReq reqDto) { - ApiUtil.validate(reqDto, null, validator); - Map apiInfInfo = getApiInfInfo(reqDto.getUserId()); - - // 0. GET 폐기관리 데이타 정보 - List dsuseMgtDtos = getDsuseMgts( - BizNimsRequest.DsuseMgtInqReq.builder() - .dscdmngIds(List.of(reqDto.getDscdmngId())) - .deptCd(apiInfInfo.get("deptCd")) - .prgrsSttsCd(null) - .build(), - false); - - if(dsuseMgtDtos.isEmpty()){ - throw ApiCustomException.create( - String.format( - "사용자[%s]의 폐기관리데이타[%s]를 확인해 주세요", - reqDto.getUserId(), - reqDto.getDscdmngId() - ) - ); - } - BizNimsResponse.DsuseMgtRes dsuseMgtDto = dsuseMgtDtos.get(0); - - NimsApiRequest.DsuseRptInfoReq rptDto = NimsApiRequest.DsuseRptInfoReq.builder() - .k(apiInfInfo.get("apiKey")) - .gc(apiInfInfo.get("deptCd")) - .se("AAR") // 보고구분: AAR-폐기 - .pg("1") // 페이지번호 - .fg("2") // 조회기준일자 : 1-보고일자, 2-취급일자 - - .sdt(dsuseMgtDto.getHdrDe()) - .edt(dsuseMgtDto.getHdrDe()) - .bc(dsuseMgtDto.getBsshCd()) - .ur(dsuseMgtDto.getUsrRptIdNo()) - .userId(reqDto.getUserId()) - .build(); - - // 폐기보고 확인(NIMS 폐기 완료 - 상태가 "확인" 인 경우 데이타 조회 추가 - List rtnList = null; - if(!isEmpty(dsuseMgtDto.getUsrRptIdNo()) && Constants.PRGRS_STTS_CD.COMPLETE.getCode().equals(dsuseMgtDto.getPrgrsSttsCd())) { - rtnList = findNimsDsuseRptsOfApi(rptDto, true); - }else { - rtnList = saveFromfindDsuseRptDataByNimsApi(rptDto); - } - - // NIMS폐기보고와 일치하는 경우 - 폐기관리ID 매핑 - for(NimsApiDto.DsuseRptInfo dto : rtnList){ - BizNimsResponse.DsuseMgtRes dsuseMgtRes = dto.mappingNewDsuseRptInfo(dsuseMgtDto); - } - - rtnList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); - return rtnList; - } - - public void modifyMappingDsuseMgt(final BizNimsRequest.DsuseMgtMappingReq reqDto){ - ApiUtil.validate(reqDto, null, validator); - reqDto.setRgtr(reqDto.getUserId()); - if(bizNimsMapper.updateMappingDsuseMgt(reqDto) != 1){ - throw ApiCustomException.create("폐기 관리 데이타 매핑 오류[폐기 관리 데이타 매핑 실패]"); - } - } - - - @Override - public void modifyPrgsSttsOfDsuseMgt(BizNimsDto.DsuseMgt reqDto) { - ApiUtil.validate(reqDto, null, validator); - reqDto.setRgtr(reqDto.getUserId()); - if(bizNimsMapper.updatePrgsSttsOfDsuseMgt(reqDto) != 1){ - throw ApiCustomException.create( - String.format( - "폐기 관리 상태 변경[%s->%s] 실패", - reqDto.getDscdmngId(), - Constants.PRGRS_STTS_CD.getName(reqDto.getPrgrsSttsCd()) - ) - ); - } - } - - @Override - public NimsApiDto.ProductInfoKd getPrdMnfSeqInfoOfBarcode(final String barcodeStr, final String userId) { - NimsApiDto.MnfSeqInfo mnfSeqInfo = new BizNimsResponse.Barcode().parseBarcode(barcodeStr); - - NimsApiRequest.ProductInfoReq prdReq = NimsApiRequest.ProductInfoReq.builder() - .fg("1") - .pg("1") - .p(mnfSeqInfo.getPrductCd()) - .dbSkipYn("N") - .userId(userId) - .build(); - List productInfoKds = saveProductInfoKd(prdReq, false); - if(productInfoKds.size() != 1) { - throw ApiCustomException.create(String.format("제품정보 오류
[Barcode 제품[%s]의 정보가 NIMS에 등록되지 않은 데이타 입니다]", mnfSeqInfo.getPrductCd())); - } - mnfSeqInfo.setPrductNm(productInfoKds.get(0).getPrductNm()); - productInfoKds.get(0).getMnfSeqInfos().add(mnfSeqInfo); - - return productInfoKds.get(0); - } - - //------------------------------------------------------------------------------------------------------ - // private method - //------------------------------------------------------------------------------------------------------ - - /** - *
-	 * 사용자ID로 API KEY 정보 조회(profile별)
-	 * - apiKey
-	 * - 관할관청코드 : deptCd - OF_CD
-	 * @param userId
-	 * @return Map API KEY 정보, 관할청 코드
-	 * 
- */ - private Map getApiInfInfo(String userId) { - if(isEmpty(userId)) { - throw ApiCustomException.create("API 연계를 위한 정보를 찾기위해 사용자 아이디(userId)는 필수입니다"); - } - return bizNimsMapper.selectApiInfInfoByUserId( - Map.of("userId", userId, "profile", Constants.PROFILE) - ).orElseThrow( - () -> ApiCustomException.create(String.format("사용자[%s]의 API KEY 정보가 존재하지 않습니다", userId)) - ); - } - - /** - *
-	 * 제품 추가 정보 set
-	 * 마약항정구분(nrcdSeNm), 중점일반구분(prtmSenm), 제조수입자명(bsshNm)
-	 * 제품최소유통단위(stdPackngStleNm), 제품낱개단위명(pceCoUnitNm) set
-	 * @param dtlList 
-	 * 
- */ - private void setDsuseMgtDtlAddProductInfo(List dtlList, String userId, String apiKey) { - for (BizNimsResponse.DsuseMgtDtlRes r : dtlList) { - // 마약항정구분(nrcdSeNm), 중점일반구분(prtmSenm) - if (isEmpty(r.getNrcdSeNm()) || isEmpty(r.getPrtmSeNm())) { - //NimsApiResult.Response result = infNimsService.getProductInfoKd( - - List list = saveProductInfoKd( - NimsApiRequest.ProductInfoReq.builder() - .k(apiKey) - .fg("1") - .pg("1") - .p(r.getPrductCd()) - .userId(userId) - .build(), - false - ); - if (isEmpty(list)) { - throw ApiCustomException.create(String.format("데이타 오류(%s[%s]제품에 해당하는 데이타가 없습니다)", r.getPrductNm(), r.getPrductCd())); - } - r.setNrcdSeNm(list.get(0).getNrcdSeNm()); - r.setPrtmSeNm(list.get(0).getPrtmSeNm()); - r.setStdPackngStleNm(list.get(0).getStdPackngStleNm()); - r.setPceCoUnitNm(list.get(0).getPceCoUnitNm()); - } - - // 제조수입자명(bsshNm) - if (isEmpty(r.getBsshNm()) && !isEmpty(r.getBsshCd())) { - List list = saveBsshInfoSt( - BsshInfoReq.builder() - .k(apiKey) - .fg("1") - .pg("1") - .bc(r.getBsshCd()) - .userId(userId) - .build() - ); - if (isEmpty(list)) { - // FIXME : 제품의 제조사[마약류식별아이디] 정보가 없는 경우가 존재 하여 exception 처리 제거 - continue; - //throw ApiCustomException.create(String.format("데이타 오류([%s]제품의 마약류취급자식별번호[%s]에 해당하는 데이타가 없습니다)", r.getPrductNm(), r.getBsshCd())); - } - r.setBsshNm(list.get(0).getBsshNm()); - } - } - } - - /** - *
-	 * NIMS API를 통해 폐기보고정보, 폐기보고 상세 생성
-	 * 1. GET 폐기보고 데이타 목록 - NIMS API 호출
-	 * 2. 신규 대상(DB에 저장되지 않은 데이타) 및 결과 return 대상 List(DB데이타중 사용여부 "Y") 선별
-	 * 3. 신규 대상중 신규(보고구분 '0')인 데이타 처리(DB 데이타 생성) & 결과 return 대상 List에 추가
-	 *    -> 신규(보고구분 '0')인 데이타 먼저 처리 -> 변경('2') 취소('1') 데이타 처리 가능
-	 * 4. 신규 대상중 취소,변경인 처리(DB 데이타 생성) & 결과 return 대상 List에 추가
-	 *    -> 0) 참조사용자보고식별번호 필수 체크
-	 *       1) 사용자보고식별번호 = 참조사용자보고식별번호 인 데이타
-	 *          tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 사용여부 'N' update
-	 *       2) 폐기 관리 테이블에 사용자보고식별번호 반영
-	 *          -> 취소인 경우는 사용자/원사용자 식별번호 clear
-	 *          -> 변경인 경우는 사용자보고식별번호 -> 참조사용자보고식별번호 update
-	 *       3) tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성
-	 *          -> 취소인 경우는 tb_dsuse_rpt_info의 사용 여부 'N'으로 생성
-	 * 5. 결과 return 대상 데이타 List에서 NIMS 변경 데이타인 경우 대상에서 제외
-	 * 6. return List에 현재 데이타 추가 - 변경인 경우만 추가
-
-	 * @param reqDto NimsApiRequest.DsuseRptInfoReq
-	 * @return List 폐기보고 목록
-	 * 
- */ - private List saveFromfindDsuseRptDataByNimsApi(NimsApiRequest.DsuseRptInfoReq reqDto) { - List nimsList = findNimsDsuseRptsOfApi(reqDto, false); - - // 신규 작업대상 데이타 List - List newList = new ArrayList<>(); - // 결과 return 작업 대상, 대상 데이타 List - List rtnList = new ArrayList<>(); - - for (NimsApiDto.DsuseRptInfo nimsDto : nimsList) { - NimsApiDto.DsuseRptInfo savedRptDto = bizNimsMapper.selectDsuseRptInfoByUsrRptIdNo(Map.of("usrRptIdNo", nimsDto.getUsrRptIdNo())); - if(isEmpty(savedRptDto)){ - newList.add(nimsDto); - - }else{ - // 기 NIMS보고조회 데이타 중 사용여부 "Y"인 데이타만 return List에 추가 - if("Y".equals(savedRptDto.getUseYn())){ - nimsDto.setOrgUsrRptIdNo(savedRptDto.getOrgUsrRptIdNo()); - rtnList.add(nimsDto); - } - }; - } - - // 3. 참조사용자보고번호가 없는 경우 처리(rptTyCd : 1 - 취소, 2 - 변경) - // -> 폐기보고 데이타 생성 & return List에 추가 - // -> 신규(보고구분 '0' or '1')인 데이타 먼저 처리해야 변경('2') 및 취소('1') 데이타 처리 가능 - // -> 취소이면서 참조사용자보고ID가 없는 경우가 있다 - // tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성 - for (NimsApiDto.DsuseRptInfo dto : newList) { - // 참조사용자보고번호가 있으면 skip - if(!isEmpty(dto.getRefUsrRptIdNo())) continue; - - // 폐기 보고 정보 데이타 생성 - createDsuseRpt(dto, reqDto.getUserId()); - - // 보고유형이 "취소"가 아닌 경우 return 목록에 추가 - if(!RPT_TY_CD.CANCEL.getCode().equals(dto.getRptTyCd())){ - rtnList.add(dto); - } - } - - // 2. 참조사용자보고번호가 있는 경우 처리(rptTyCd : 1 - 취소, 2 - 변경) - String errMsg = null; - // thread safe 하도록 CopyOnWriteArrayList 사용 - // List 사용시 java.util.ConcurrentModificationException 발생 - 동시성 문제 - CopyOnWriteArrayList concurrentList = new CopyOnWriteArrayList<>(rtnList); - for (NimsApiDto.DsuseRptInfo dto : newList) { - dto.setRgtr(reqDto.getUserId()); - - // 참조사용자보고번호가 없으면 skip - if(isEmpty(dto.getRefUsrRptIdNo())) continue; - - // 2-3. tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성 (취소인 경우는 tb_dsuse_rpt_info의 사용 여부 'N'으로 생성) - createDsuseRpt(dto, reqDto.getUserId()); - - // 2-2. 폐기보고정보, 폐기관리 변경 - // 1) tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 사용여부 'N' update - updateDsuseRptOfCancel(dto, reqDto.getUserId()); - - for(NimsApiDto.DsuseRptInfo item : concurrentList){ - if(item.getOrgUsrRptIdNo().equals(dto.getOrgUsrRptIdNo()) - && item.getUsrRptIdNo().equals(dto.getRefUsrRptIdNo())){ - concurrentList.remove(item); - concurrentList.add(dto); - } - } - } - return new ArrayList<>(concurrentList); - } - - /** - * - * @param reqDto NimsApiRequest.DsuseRptInfoReq - * @param isConfirmed "확인" 상태의 데이타 조회 여부 - * @return List - */ - private List findNimsDsuseRptsOfApi(NimsApiRequest.DsuseRptInfoReq reqDto, boolean isConfirmed) { - List nimsList = new ArrayList<>(); - - while(true) { - NimsApiResult.Response rslt = infNimsService.getDsuseRptInfo(reqDto); - List curList = rslt.getResultOrThrow(); - - if(isEmpty(curList)) break; - - // FIXME: 2024-06-28 데이타 검증후 fix - // 사용자보고번호가 있는 경우 또는 상태가 "확인"이 아니 경우만 추가 - nimsList.addAll( - curList.stream() - //.filter(d -> !RPT_TY_CD.CANCEL.getCode().equals(d.getRptTyCd())) - .filter(d -> isConfirmed || !"확인".equals(d.getStatus())) - .toList() - ); - - if(rslt.isEndYn()) break; - reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); - } - nimsList.forEach(d -> d.setRptTyNm(RPT_TY_CD.getName(d.getRptTyCd()))); - nimsList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); - return nimsList; - } - - /** - *
-	 * tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성
-	 * 0) 부가 정보 set
-	 * 1) 원사용자보고식별번호 set
-	 * 2) 데이타 생성
-	 *   - 취소인 경우는 tb_dsuse_rpt_info의 사용 여부 'N'으로 생성
-	 *
-	 * @param dto NimsApiDto.DsuseRptInfo
-	 * 
- */ - private void createDsuseRpt(final NimsApiDto.DsuseRptInfo dto, String userId) { - dto.setRgtr(userId); - dto.setRptTyNm(RPT_TY_CD.getName(dto.getRptTyCd())); - dto.setDsuseSeNm(Constants.DSUSE_SE_CD.getName(dto.getDsuseSeCd())); - dto.setDsusePrvNm(Constants.DSUSE_PRV_CD.getName(dto.getDsusePrvCd())); - dto.setDsuseMthNm(Constants.DSUSE_MTH_CD.getName(dto.getDsuseMthCd())); - - // 참조사용자보고번호가 없으면 -> 원사용자보고식별번호 = 사용자보고식별번호 - if(isEmpty(dto.getRefUsrRptIdNo())){ - dto.setOrgUsrRptIdNo(dto.getUsrRptIdNo()); - }else{ - // FIXME: 2024-06-17 참조사용자보고번호와 사용자보고식별번호가 같으면 skip - // 참조사용자보고번호와 사용자보고식별번호가 같으면 -> 원사용자보고식별번호 = 사용자보고식별번호 - if(dto.getRefUsrRptIdNo().equals(dto.getUsrRptIdNo())){ - dto.setOrgUsrRptIdNo(dto.getUsrRptIdNo()); - }else { - // 참조사용자보고번호가 있으면, 원사용자보고식별번호 조회 - findRecusiveOrgUsrRptIdNo(dto); - } - } - - if (bizNimsMapper.insertDsuseRptInfo(dto) == 1) { - - int dtlCnt = 0; - for (NimsApiDto.DsuseRptInfoDtl d : dto.getListDtl()) { - d.setRgtr(userId); - dtlCnt = dtlCnt + bizNimsMapper.insertDsuseRptInfoDtl(d); - } - if (dto.getRndDtlRptCnt() != dtlCnt) - throw ApiCustomException.create("폐기 정보 상세 등록 실패"); - } else { - throw ApiCustomException.create("폐기 정보 등록 실패"); - } - } - - /** - *
-	 * 취소 또는 변경(rptTyCd : 1, 2)시 원사용자보고식별번호 조회 및 설정
-	 * 참조사용자보고식별번호 필수
-	 * => 사용자보고식별번호 = 참조사용자식별번호 조건 으로 조회
-	 * => 조회결과 참조사용자식별번호가 존재하지 않을때 까지 반복 조회(신규(rptTyCd : 0)인 경우 까지)
-	 * => 사용자보고식별번호를 원사용자보고식별번호로 설정
-	 * @param dto NIMS 폐기보고 데이타(NimsApiDto.DsuseRptInfo)
-	 * 
- */ - private void findRecusiveOrgUsrRptIdNo(NimsApiDto.DsuseRptInfo dto) { - // 원 사용자 식별 번호 set - 변경/취소 인 경우 - // 신규인 경우는 사용자보고식별번호로 설정 - String refUsrRptIdNo = dto.getRefUsrRptIdNo(); - - // 참조사용자보고식별번호로 원사용자보고식별번호조회 - while(true) { - Map map = bizNimsMapper.recusiveRefUsrRptIdNo(refUsrRptIdNo); - if(map == null){ - // 참조사용자식별번호가 없는 경우도 있어(NIMS보고상태 "확인"이 아닌 경우에) skip - //dto.setOrgUsrRptIdNo(dto.getRefUsrRptIdNo()); - //throw ApiCustomException.create("데이타 오류[참조사용자로 사용자보고식별번호 조회 실패 - 데이타 누락]"); - log.error("데이타 오류[참조사용자로 사용자보고식별번호 조회 실패 - 데이타 누락]"); - break; - } - - // 참조사용자보고식별번호가 있으면 계속 조회 - if(!isEmpty(map.get("refUsrRptIdNo"))){ - refUsrRptIdNo = map.get("refUsrRptIdNo"); - continue; - } - - // 참조사용자보고식별번호가 없으면 -> 원사용자보고식별번호 = 사용자보고식별번호로 설정 - dto.setOrgUsrRptIdNo(map.get("usrRptIdNo")); - break; - } - } - - /** - *
-	 * - tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl
-	 *   사용자보고식별번호 = 참조사용자보고식별번호 인 데이타
-	 *   => tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 사용여부 'N' update
-	 * - tb_dsuse_mgt
-	 *   폐기 관리 테이블에 사용자보고식별번호 반영
-	 *   => 취소인 경우는 사용자/원사용자 식별번호 clear
-	 *   => 변경인 경우는 사용자보고식별번호 -> 참조사용자보고식별번호 update
-	 * @param dto NimsApiDto.DsuseRptInfo
-	 * 
- */ - private void updateDsuseRptOfCancel(NimsApiDto.DsuseRptInfo dto, String userId) { - dto.setRgtr(userId); - String errMsg; - if (RPT_TY_CD.CANCEL.getCode().equals(dto.getRptTyCd())) errMsg = RPT_TY_CD.CANCEL.getNm(); - else errMsg = RPT_TY_CD.MODIFY.getNm(); - - if (bizNimsMapper.updateCancelDsuseRptInfo(dto) == 1) { - int cnt = bizNimsMapper.updateCancelDsuseRptInfoDtl(dto); - - } else { - // FIXME: 2024-06-17 실패시 처리 방안 확인 필요?? - log.error("폐기 정보 {} 실패", errMsg); - //throw ApiCustomException.create(String.format("폐기 정보 %s 실패", errMsg)); - } - } - - /** - *
-	 * 상품정보에 제조번호 목록 추가
-	 * @param list List
-	 * @param apiKey Api Key
-	 * 
- */ - private void productInfoaddMnfSeqs(final List list, final String apiKey) { - String productCd = ""; - - try { + private final InfNimsService infNimsService; + private final BizNimsMapper bizNimsMapper; + private final FileService fileService; + + //------------------------------------------------------------------------------------------------------ + // NIMS API CALL + //------------------------------------------------------------------------------------------------------ + @Override + public ApiBaseResponse> getBsshInfoSt(BsshInfoReq reqDto) { + if(isEmpty(reqDto.getBc()) && isEmpty(reqDto.getBi()) && isEmpty(reqDto.getBn())){ + throw ApiCustomException.create("업체[사업자] 번호 또는 명, 사업자등록번호 중 하나는 필수 입니다"); + } + if(!isEmpty(reqDto.getBn()) && reqDto.getBn().length() < 3) { + throw ApiCustomException.create("업체[사업자]명은 3자 이상 으로 조회해 주세요"); + } + + // DB 조회 + List list = new ArrayList<>(); + + if(isEmpty(reqDto.getK())){ + reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); + } + reqDto.setFg("1"); // 조회범위(1-전체,2-내거래처) + reqDto.setFg2("1"); // 조회범위2(1:NK(취급승인)포함 - default, 2:NK(취급승인)제외) + + boolean isRprsntvNm = !isEmpty(reqDto.getRprsntvNm());//while(true) { + int totalCount = 0; + do { + // 마약류취급자식별번호로 마약류취급자정보 조회 + NimsApiResult.Response rslt = infNimsService.getBsshInfoSt(reqDto); + List curList = rslt.getResult(); + + if (!isRprsntvNm) { + totalCount = rslt.getBody().getTotalCount(); + list.addAll(curList); + break; + } + + // 대표자 검색이 있는 경우 NIMS 데이타 전체 조회 + list.addAll( + curList.stream() + .filter(d -> !isEmpty(d.getRprsntvNm()) && d.getRprsntvNm().contains(reqDto.getRprsntvNm())) + .toList()); + totalCount = list.size(); + if(rslt.isEndYn()) break; + reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); + + } while(true); + + ApiBaseResponse> res = ApiBaseResponse.of(list); + res.setTotalCount(totalCount); + return res; + } + + + /** + *
+     *     업체정보를 업체코드로 조회후 DB 저장
+     *     제품의 제조업체 조회시 사용 - 결과는 단건
+     * @param reqDto NimsApiRequest.BsshInfoRequest
+     * @return List
+     * 
+ */ + @Override + public List saveBsshInfoStQueryBsshInfoByBsshCd(BsshInfoReq reqDto) { + if(isEmpty(reqDto.getBc()) && isEmpty(reqDto.getBi()) && isEmpty(reqDto.getBn())){ + throw ApiCustomException.create("업체[사업자] 번호 또는 명, 사업자등록번호 중 하나는 필수 입니다"); + } + + if(isEmpty(reqDto.getK())){ + reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); + } + reqDto.setFg("1"); // 조회범위(1-전체,2-내거래처) + reqDto.setPg("1"); // 조회페이지 + reqDto.setFg2("1"); // 조회범위2(1:NK(취급승인)포함 - default, 2:NK(취급승인)제외) + + // 마약류취급자식별번호로 마약류취급자정보 조회 + NimsApiResult.Response rslt = infNimsService.getBsshInfoSt(reqDto); + List curList = rslt.getResult(); + + for (BsshInfoSt d : curList) { + d.setRgtr(reqDto.getUserId()); + bizNimsMapper.mergeBsshInfoSt(d); + } + return curList; + } + + @Override + public ApiBaseResponse> getProductInfoKd(NimsApiRequest.ProductInfoReq reqDto, boolean isMnfSeqInfo) { + if(isEmpty(reqDto.getP()) && isEmpty(reqDto.getPn())){ + throw ApiCustomException.create("상품번호 또는 상품명중 하나는 필수 입니다"); + } + + if(!isEmpty(reqDto.getPn()) && reqDto.getPn().length() < 2){ + throw ApiCustomException.create("상품명은 2자 이상 으로 조회해 주세요"); + } + + if(isEmpty(reqDto.getK())){ + reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); + } + reqDto.setFg("1"); // 조회범위(1-전체,2-내거래처품목,3-청구코드매핑) + reqDto.setFg2(""); // 중점일반구분(all, 1:중점, 2:일반) + + // 제품코드로 제품정보 조회 + NimsApiResult.Response rslt = infNimsService.getProductInfoKd(reqDto); + List curList = rslt.getResult(); + + if(isEmpty(curList)) return ApiBaseResponse.of(curList); + + // 제조 번호, 일련번호, 유효기간 정보 목록 추가 + if(isMnfSeqInfo) productInfoaddMnfSeqs(curList, reqDto.getBc(), reqDto.getK()); + ApiBaseResponse> res = ApiBaseResponse.of(curList); + res.setTotalCount(rslt.getBody().getTotalCount()); + return res; + } + + /** + *
+     *     DB에서 먼저 조회(dbSkipYn = 'Y' 인 경우는 DB 조회 skip)
+     *     -> 조회 결과가 없는 경우 API 조회
+     *     상품정보 조회후 DB 저장
+     *     제조번호 조회 여부에 따라 제조번호, 일련번호, 유효기간 정보 목록 추가
+     *     조회 건수를 제한하기 위해 조회 조건 강제 - 상품번호 또는 상품명(2자 이상) 필수
+     * @param reqDto NimsApiRequest.ProductInfoRequest
+     * @param isMnfSeqInfo 제조번호 조회 여부
+     * @return
+     * 
+ */ + @Override + public List saveProductInfoKdQueryProductByProductId(NimsApiRequest.ProductInfoReq reqDto, boolean isMnfSeqInfo) { + if(isEmpty(reqDto.getP()) && isEmpty(reqDto.getPn())){ + throw ApiCustomException.create("상품번호 또는 상품명중 하나는 필수 입니다"); + } + + if(!isEmpty(reqDto.getPn()) && reqDto.getPn().length() < 2){ + throw ApiCustomException.create("상품명은 2자 이상 으로 조회해 주세요"); + } + + if(isEmpty(reqDto.getK())){ + reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); + } + reqDto.setFg2(""); // 중점일반구분(all, 1:중점, 2:일반) + + // 제품코드로 제품정보 조회 + NimsApiResult.Response rslt = infNimsService.getProductInfoKd(reqDto); + List curList = rslt.getResult(); + + if(isEmpty(curList)) return curList; + + //FIXME: 신규 API 적용 - 조회 결과 저장 skip + // for (NimsApiDto.ProductInfoKd d : curList) { + // d.setRgtr(reqDto.getUserId()); + // bizNimsMapper.mergeProductInfoKd(d); + // } + + // 제조 번호, 일련번호, 유효기간 정보 목록 추가 + if(isMnfSeqInfo) productInfoaddMnfSeqs(curList, reqDto.getBc(), reqDto.getK()); + return curList; + } + + @Override + public ApiBaseResponse> getMnfSeqInfo(NimsApiRequest.MnfSeqInfoReq reqDto) { + if(isEmpty(reqDto.getK())){ + reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); + } + //reqDto.setFg("1"); // 제조번호 또는 일련번호 구분(1-제조번호, 2-일련번호, 3-바코드/RFID) + //reqDto.setPg("1"); // 조회페이지 + + + NimsApiResult.Response rslt = infNimsService.getMnfSeqInfo(reqDto); + List list = rslt.getResult(); + + // 시리얼번호 및 제조번호 기준 검색후, 결과내에서 유효기간으로 필터링 하도록 처리 + if(!isEmpty(list) && (!isEmpty(reqDto.getT()) && !isEmpty(reqDto.getVd()))) { + list.sort((a, b) -> { + if (isEmpty(a.getPrdValidDe()) && isEmpty(b.getPrdValidDe())) + return 0; + if (isEmpty(a.getPrdValidDe())) + return -1; + if (isEmpty(b.getPrdValidDe())) + return 1; + return a.getPrdValidDe().compareTo(b.getPrdValidDe()); + }); + } + + ApiBaseResponse> res = ApiBaseResponse.of(list); + res.setTotalCount(rslt.getBody().getTotalCount()); + return res; + } + + @Override + public List getJurisdictionGovInfo(final NimsApiRequest.JurisdictionGovInfoReq reqDto) { + List list = new ArrayList<>(); + + // DB 조회 : 주소검색이면 DB 조회 skip + if("N".equals(reqDto.getDbSkipYn()) && isEmpty(reqDto.getAdr())) { + list = bizNimsMapper.selectJurisdictionGovInfos(reqDto); + if (!isEmpty(list)){ + return list; + } + } + + reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); + while(true) { + // 기관정보 조회 + NimsApiResult.Response rslt = infNimsService.getJurisdictionGovInfo(reqDto); + List curList = rslt.getResult(); + + if(isEmpty(curList)) break; + for(NimsApiDto.JurisdictionGovInfo d : curList) { + d.setRgtr(reqDto.getUserId()); + bizNimsMapper.mergeJurisdictionGovInfo(d); + } + list.addAll(curList); + + if(rslt.isEndYn()) break; + reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); + } + return list; + } + + @Override + public List getNimsDsuseRptInfo(NimsApiRequest.DsuseRptInfoReq reqDto) { + reqDto.setFg("2"); // 조회기준일자(1-보고일,2-취급일) + reqDto.setPg("1"); // 조회 페이지 + reqDto.setSe("AAR"); // 보고구분코드 - 폐기 + + Map apiInfInfo = getApiInfInfo(reqDto.getUserId()); + reqDto.setK(apiInfInfo.get("apiKey")); + reqDto.setGc(apiInfInfo.get("deptCd")); // 관할관청코드 + ApiUtil.validate(reqDto, null, validator); + + List rtnList = findNimsDsuseRptsOfApi(reqDto, false); + + rtnList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); + return rtnList; + } + //------------------------------------------------------------------------------------------------------ + // NIMS BIZ + //------------------------------------------------------------------------------------------------------ + /** + *
+     * 사고마약류폐기 신청 접수
+     * @param reqDto BizNimsRequest.DsuseMgtReceipt
+     * @return BizNimsRequest.DsuseMgtReceipt 생성된 폐기관리 정보
+     * 
+ */ + @Override + public BizNimsRequest.DsuseMgtReceiptReq saveDsuseMgtReceipt(final BizNimsRequest.DsuseMgtReceiptReq reqDto, final List dtls, final List files, final NimsApiDto.BsshInfoSt bsshInfoSt, final List prdList) { + ApiUtil.validate(reqDto, null, validator); + if(reqDto.getRndDtlRptCnt() != dtls.size()) throw ApiCustomException.create("폐기물 보고수 오류[폐기물 갯수 확인]"); + ApiUtil.validate(dtls, null, validator); + reqDto.setRgtr(reqDto.getUserId()); + + if(files.size() != dtls.size()) throw ApiCustomException.create("폐기물 파일 갯수 오류[파일 갯수 확인]"); + + // FIXME: 신규 API 적용 - 취급자 및 제품 정보 저장 + bsshInfoSt.setRgtr(reqDto.getUserId()); + bizNimsMapper.mergeBsshInfoSt(bsshInfoSt); + prdList.forEach( + d -> { + d.setRgtr(reqDto.getUserId()); + bizNimsMapper.mergeProductInfoKd(d); + } + ); + + if(isEmpty(reqDto.getDscdmngId())) { + + if (bizNimsMapper.insertDsuseMgtReceipt(reqDto) == 1) { + + // 폐기관리 상세 등록 + saveDsuseMgtDtls(reqDto, dtls, files); + } else { + throw ApiCustomException.create("폐기 관리 마스터 등록 실패"); + } + } else { + bizNimsMapper.updateDsuseMgtReceipt(reqDto); + + // 파일 삭제 + String[] fileIds = bizNimsMapper.selectFileId( + Map.of("infType", Constants.FILE_INF_TYPE.DSUSE_PRD_IMG.getCode(), "infKey", reqDto.getDscdmngId())); + if (fileIds.length > 0) { + fileService.delete(fileIds); + + } + // 폐기관리 상세 삭제 + bizNimsMapper.deleteDsuseMgtDtl(reqDto.getDscdmngId()); + + // 폐기관리 상세 등록 + saveDsuseMgtDtls(reqDto, dtls, files); + } + return reqDto; + } + + @Override + public BizNimsRequest.DsuseMgtReceiptReq modifyDsuseMgtReceiptMstInfo(BizNimsRequest.DsuseMgtReceiptReq reqDto) { + bizNimsMapper.updateDsuseMgtReceipt(reqDto); + return reqDto; + } + + /** + *
+     * 사고마약류폐기 통보[결과]처리
+     * @param reqDto BizNimsRequest.DsuseMgtRslt
+     * @return BizNimsRequest.DsuseMgtRslt 생성된 폐기관리 정보
+     * 
+ */ + public BizNimsRequest.DsuseMgtRsltReq saveDsuseMgtRslt(final BizNimsRequest.DsuseMgtRsltReq reqDto, final List files, final String fileChangeYn) { + ApiUtil.validate(reqDto, null, validator); + reqDto.setRgtr(reqDto.getUserId()); + + // ------------------------------------------------------------------------------------------------ + // 폐기장소 변경 여부 체크 - 폐기 결과를 공유하는 데이타 + // 폐기구분, 폐기일자, 폐기방법이 동일한 건에 대하여 폐기장소 일괄 변경 + // ------------------------------------------------------------------------------------------------ + // 폐기장소가 null인 경우 - request 데이타로 set + final String dsuseLoc = bizNimsMapper.selectCheckDsuseLocBydscdmngId(reqDto.getDscdmngId()) + .orElse(reqDto.getDsuseLoc()); + + // 1. 폐기장소가 null(또는 "")인 경우 - 신규 저장 -> 폐기장소 저장으로 이동 + // 2. 1이 아니고, 저장된 폐기장소와 request 폐기장소가 다르면 해당 데이타를 공유하는 모든건 변경 + if(!isEmpty(dsuseLoc) && !reqDto.getDsuseLoc().equals(dsuseLoc)){ + bizNimsMapper.updateDsuseLocOfDsuseMgt(reqDto); + } + // ------------------------------------------------------------------------------------------------ + + if(bizNimsMapper.updateDsuseMgtRslt(reqDto) == 1){ + if("Y".equals(fileChangeYn)) { + Map map = Map.of("infType", Constants.FILE_INF_TYPE.DSUSE_IMG.getCode(), "infKey", reqDto.getDscdmngId()); + // 파일 삭제 + String[] fileIds = bizNimsMapper.selectFileId(map); + if (fileIds.length > 0) { + fileService.delete(fileIds); + } + // DB 파일 정보 삭제 + bizNimsMapper.deleteFileInfo(map); + + if(files != null) { + int idx = 1; + for (MultipartFile mf : files) { + uploadFileSave(Constants.FILE_INF_TYPE.DSUSE_IMG.getCode(), reqDto.getDscdmngId(), + String.valueOf(idx), mf); + idx++; + } + } + + } + + } else { + throw ApiCustomException.create("폐기 관리 정보 변경[통보(결과) 처리] 실패"); + } + return reqDto; + } + + /** + *
+     * 사고 마약류 폐기 관리 목록 조회
+     * 1. 사고마약류 폐기관리 목록 조회
+     * 2. 사고마약류 결과결과[통보]서, 폐기내역 및 사진 문서 작성을 위한 데이타 조회
+     * @param reqDto BizNimsRequest.DsuseMgtInq
+     * @param isForDoc true: 문서작성용, false: 조회용
+     * @return List 조회된 폐기 관리 목록
+     * 
+ */ + @Override + public List getDsuseMgts(final BizNimsRequest.DsuseMgtInqReq reqDto, final boolean isForDoc) { + List resList = bizNimsMapper.selectDsuseMgts(reqDto); + String apiKey = null; + if(isForDoc) apiKey = getApiInfInfo(reqDto.getUserId()).get("apiKey"); + + for (BizNimsResponse.DsuseMgtRes dto : resList) { + dto.setRptTyNm(RPT_TY_CD.getName(dto.getRptTyCd())); + dto.setDsuseSeNm(Constants.DSUSE_SE_CD.getName(dto.getDsuseSeCd())); + dto.setDsusePrvNm(Constants.DSUSE_PRV_CD.getName(dto.getDsusePrvCd())); + dto.setDsuseMthNm(Constants.DSUSE_MTH_CD.getName(dto.getDsuseMthCd())); + + Map map = new HashMap<>(); + map.put("dscdmngId", dto.getDscdmngId()); + List dsuseRptInfoDtls = bizNimsMapper.selectDsuseMgtDtls(map); + if(isForDoc) setDsuseMgtDtlAddProductInfo(dsuseRptInfoDtls, reqDto.getUserId(), apiKey); + dto.getDsuseMgtDtls().addAll(dsuseRptInfoDtls); + } + + return resList; + } + + @Override + public List saveDsuseRptInfo(NimsApiRequest.DsuseRptInfoReq reqDto) { + reqDto.setFg("2"); // 조회기준일자(1-보고일,2-취급일) + reqDto.setPg("1"); // 조회 페이지 + reqDto.setSe("AAR"); // 보고구분코드 - 폐기 + + Map apiInfInfo = getApiInfInfo(reqDto.getUserId()); + reqDto.setK(apiInfInfo.get("apiKey")); + reqDto.setGc(apiInfInfo.get("deptCd")); // 관할관청코드 + ApiUtil.validate(reqDto, null, validator); + + List rtnList = saveFromfindDsuseRptDataByNimsApi(reqDto); + + rtnList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); + return rtnList; + } + + /** + *
+     * saveDsuseRptInfo 대체 메소드 - 확인후 적용
+
+     * 6. return List에 현재 데이타 추가 - 변경인 경우만 추가
+     * 8. 결과 sort 및 return
+     * @param reqDto
+     * @return
+     * 
+ */ + @Override + public List getDsuseRptAndDsuseMgtMapping(BizNimsRequest.DsuseRptMappingInqReq reqDto) { + ApiUtil.validate(reqDto, null, validator); + Map apiInfInfo = getApiInfInfo(reqDto.getUserId()); + + // 0. GET 폐기관리 데이타 정보 + List dsuseMgtDtos = getDsuseMgts( + BizNimsRequest.DsuseMgtInqReq.builder() + .dscdmngIds(List.of(reqDto.getDscdmngId())) + .deptCd(apiInfInfo.get("deptCd")) + .prgrsSttsCd(null) + .build(), + false); + + if(dsuseMgtDtos.isEmpty()){ + throw ApiCustomException.create( + String.format( + "사용자[%s]의 폐기관리데이타[%s]를 확인해 주세요", + reqDto.getUserId(), + reqDto.getDscdmngId() + ) + ); + } + BizNimsResponse.DsuseMgtRes dsuseMgtDto = dsuseMgtDtos.get(0); + + NimsApiRequest.DsuseRptInfoReq rptDto = NimsApiRequest.DsuseRptInfoReq.builder() + .k(apiInfInfo.get("apiKey")) + .gc(apiInfInfo.get("deptCd")) + .se("AAR") // 보고구분: AAR-폐기 + .pg("1") // 페이지번호 + .fg("2") // 조회기준일자 : 1-보고일자, 2-취급일자 + + .sdt(dsuseMgtDto.getHdrDe()) + .edt(dsuseMgtDto.getHdrDe()) + .bc(dsuseMgtDto.getBsshCd()) + .ur(dsuseMgtDto.getUsrRptIdNo()) + .userId(reqDto.getUserId()) + .build(); + + // 폐기보고 확인(NIMS 폐기 완료 - 상태가 "확인" 인 경우 데이타 조회 추가 + List rtnList = null; + if(!isEmpty(dsuseMgtDto.getUsrRptIdNo()) && Constants.PRGRS_STTS_CD.COMPLETE.getCode().equals(dsuseMgtDto.getPrgrsSttsCd())) { + rtnList = findNimsDsuseRptsOfApi(rptDto, true); + }else { + rtnList = saveFromfindDsuseRptDataByNimsApi(rptDto); + } + + // NIMS폐기보고와 일치하는 경우 - 폐기관리ID 매핑 + for(NimsApiDto.DsuseRptInfo dto : rtnList){ + BizNimsResponse.DsuseMgtRes dsuseMgtRes = dto.mappingNewDsuseRptInfo(dsuseMgtDto); + } + + rtnList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); + return rtnList; + } + + public void modifyMappingDsuseMgt(final BizNimsRequest.DsuseMgtMappingReq reqDto){ + ApiUtil.validate(reqDto, null, validator); + reqDto.setRgtr(reqDto.getUserId()); + if(bizNimsMapper.updateMappingDsuseMgt(reqDto) != 1){ + throw ApiCustomException.create("폐기 관리 데이타 매핑 오류[폐기 관리 데이타 매핑 실패]"); + } + } + + + @Override + public void modifyPrgsSttsOfDsuseMgt(BizNimsDto.DsuseMgt reqDto) { + ApiUtil.validate(reqDto, null, validator); + reqDto.setRgtr(reqDto.getUserId()); + if(bizNimsMapper.updatePrgsSttsOfDsuseMgt(reqDto) != 1){ + throw ApiCustomException.create( + String.format( + "폐기 관리 상태 변경[%s->%s] 실패", + reqDto.getDscdmngId(), + Constants.PRGRS_STTS_CD.getName(reqDto.getPrgrsSttsCd()) + ) + ); + } + } + + @Override + public NimsApiDto.ProductInfoKd getPrdMnfSeqInfoOfBarcode(final String barcodeStr, final String userId) { + NimsApiDto.MnfSeqInfo mnfSeqInfo = new BizNimsResponse.Barcode().parseBarcode(barcodeStr); + + NimsApiRequest.ProductInfoReq prdReq = NimsApiRequest.ProductInfoReq.builder() + .fg("1") + .pg("1") + .p(mnfSeqInfo.getPrductCd()) + .userId(userId) + .build(); + List productInfoKds = saveProductInfoKdQueryProductByProductId(prdReq, false); + if(productInfoKds.size() != 1) { + throw ApiCustomException.create(String.format("제품정보 오류
[Barcode 제품[%s]의 정보가 NIMS에 등록되지 않은 데이타 입니다]", mnfSeqInfo.getPrductCd())); + } + mnfSeqInfo.setPrductNm(productInfoKds.get(0).getPrductNm()); + productInfoKds.get(0).getMnfSeqInfos().add(mnfSeqInfo); + + return productInfoKds.get(0); + } + + //------------------------------------------------------------------------------------------------------ + // private method + //------------------------------------------------------------------------------------------------------ + + /** + *
+     * 사용자ID로 API KEY 정보 조회(profile별)
+     * - apiKey
+     * - 관할관청코드 : deptCd - OF_CD
+     * @param userId
+     * @return Map API KEY 정보, 관할청 코드
+     * 
+ */ + private Map getApiInfInfo(String userId) { + if(isEmpty(userId)) { + throw ApiCustomException.create("API 연계를 위한 정보를 찾기위해 사용자 아이디(userId)는 필수입니다"); + } + return bizNimsMapper.selectApiInfInfoByUserId( + Map.of("userId", userId, "profile", Constants.PROFILE) + ).orElseThrow( + () -> ApiCustomException.create(String.format("사용자[%s]의 API KEY 정보가 존재하지 않습니다", userId)) + ); + } + + /** + *
+     * 제품 추가 정보 set
+     * 마약항정구분(nrcdSeNm), 중점일반구분(prtmSenm), 제조수입자명(bsshNm)
+     * 제품최소유통단위(stdPackngStleNm), 제품낱개단위명(pceCoUnitNm) set
+     * @param dtlList 
+     * 
+ */ + private void setDsuseMgtDtlAddProductInfo(List dtlList, String userId, String apiKey) { + for (BizNimsResponse.DsuseMgtDtlRes r : dtlList) { + + // 마약항정구분(nrcdSeNm), 중점일반구분(prtmSenm) + if (isEmpty(r.getNrcdSeNm()) || isEmpty(r.getPrtmSeNm())) { + List list = saveProductInfoKdQueryProductByProductId( + NimsApiRequest.ProductInfoReq.builder() + .k(apiKey) + .fg("1") + .pg("1") + .p(r.getPrductCd()) + .userId(userId) + .build(), + false + ); + if (isEmpty(list)) { + throw ApiCustomException.create(String.format("데이타 오류(%s[%s]제품에 해당하는 데이타가 없습니다)", r.getPrductNm(), r.getPrductCd())); + } + r.setNrcdSeNm(list.get(0).getNrcdSeNm()); + r.setPrtmSeNm(list.get(0).getPrtmSeNm()); + r.setStdPackngStleNm(list.get(0).getStdPackngStleNm()); + r.setPceCoUnitNm(list.get(0).getPceCoUnitNm()); + } + + // 제조수입자명(bsshNm) + if (isEmpty(r.getBsshNm()) && !isEmpty(r.getBsshCd())) { + List list = saveBsshInfoStQueryBsshInfoByBsshCd( + BsshInfoReq.builder() + .k(apiKey) + .fg("1") + .pg("1") + .bc(r.getBsshCd()) + .userId(userId) + .build() + ); + if (isEmpty(list)) { + // FIXME : 제품의 제조사[마약류식별아이디] 정보가 없는 경우가 존재 하여 exception 처리 제거 + continue; + //throw ApiCustomException.create(String.format("데이타 오류([%s]제품의 마약류취급자식별번호[%s]에 해당하는 데이타가 없습니다)", r.getPrductNm(), r.getBsshCd())); + } + r.setBsshNm(list.get(0).getBsshNm()); + } + } + } + + /** + *
+     * NIMS API를 통해 폐기보고정보, 폐기보고 상세 생성
+     * 1. GET 폐기보고 데이타 목록 - NIMS API 호출
+     * 2. 신규 대상(DB에 저장되지 않은 데이타) 및 결과 return 대상 List(DB데이타중 사용여부 "Y") 선별
+     * 3. 신규 대상중 신규(보고구분 '0')인 데이타 처리(DB 데이타 생성) & 결과 return 대상 List에 추가
+     *    -> 신규(보고구분 '0')인 데이타 먼저 처리 -> 변경('2') 취소('1') 데이타 처리 가능
+     * 4. 신규 대상중 취소,변경인 처리(DB 데이타 생성) & 결과 return 대상 List에 추가
+     *    -> 0) 참조사용자보고식별번호 필수 체크
+     *       1) 사용자보고식별번호 = 참조사용자보고식별번호 인 데이타
+     *          tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 사용여부 'N' update
+     *       2) 폐기 관리 테이블에 사용자보고식별번호 반영
+     *          -> 취소인 경우는 사용자/원사용자 식별번호 clear
+     *          -> 변경인 경우는 사용자보고식별번호 -> 참조사용자보고식별번호 update
+     *       3) tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성
+     *          -> 취소인 경우는 tb_dsuse_rpt_info의 사용 여부 'N'으로 생성
+     * 5. 결과 return 대상 데이타 List에서 NIMS 변경 데이타인 경우 대상에서 제외
+     * 6. return List에 현재 데이타 추가 - 변경인 경우만 추가
+
+     * @param reqDto NimsApiRequest.DsuseRptInfoReq
+     * @return List 폐기보고 목록
+     * 
+ */ + private List saveFromfindDsuseRptDataByNimsApi(NimsApiRequest.DsuseRptInfoReq reqDto) { + List nimsList = findNimsDsuseRptsOfApi(reqDto, false); + + // 신규 작업대상 데이타 List + List newList = new ArrayList<>(); + // 결과 return 작업 대상, 대상 데이타 List + List rtnList = new ArrayList<>(); + + for (NimsApiDto.DsuseRptInfo nimsDto : nimsList) { + NimsApiDto.DsuseRptInfo savedRptDto = bizNimsMapper.selectDsuseRptInfoByUsrRptIdNo(Map.of("usrRptIdNo", nimsDto.getUsrRptIdNo())); + if(isEmpty(savedRptDto)){ + newList.add(nimsDto); + + }else{ + // 기 NIMS보고조회 데이타 중 사용여부 "Y"인 데이타만 return List에 추가 + if("Y".equals(savedRptDto.getUseYn())){ + nimsDto.setOrgUsrRptIdNo(savedRptDto.getOrgUsrRptIdNo()); + rtnList.add(nimsDto); + } + }; + } + + // 3. 참조사용자보고번호가 없는 경우 처리(rptTyCd : 1 - 취소, 2 - 변경) + // -> 폐기보고 데이타 생성 & return List에 추가 + // -> 신규(보고구분 '0' or '1')인 데이타 먼저 처리해야 변경('2') 및 취소('1') 데이타 처리 가능 + // -> 취소이면서 참조사용자보고ID가 없는 경우가 있다 + // tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성 + for (NimsApiDto.DsuseRptInfo dto : newList) { + // 참조사용자보고번호가 있으면 skip + if(!isEmpty(dto.getRefUsrRptIdNo())) continue; + + // 폐기 보고 정보 데이타 생성 + createDsuseRpt(dto, reqDto.getUserId()); + + // 보고유형이 "취소"가 아닌 경우 return 목록에 추가 + if(!RPT_TY_CD.CANCEL.getCode().equals(dto.getRptTyCd())){ + rtnList.add(dto); + } + } + + // 2. 참조사용자보고번호가 있는 경우 처리(rptTyCd : 1 - 취소, 2 - 변경) + String errMsg = null; + // thread safe 하도록 CopyOnWriteArrayList 사용 + // List 사용시 java.util.ConcurrentModificationException 발생 - 동시성 문제 + CopyOnWriteArrayList concurrentList = new CopyOnWriteArrayList<>(rtnList); + for (NimsApiDto.DsuseRptInfo dto : newList) { + dto.setRgtr(reqDto.getUserId()); + + // 참조사용자보고번호가 없으면 skip + if(isEmpty(dto.getRefUsrRptIdNo())) continue; + + // 2-3. tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성 (취소인 경우는 tb_dsuse_rpt_info의 사용 여부 'N'으로 생성) + createDsuseRpt(dto, reqDto.getUserId()); + + // 2-2. 폐기보고정보, 폐기관리 변경 + // 1) tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 사용여부 'N' update + updateDsuseRptOfCancel(dto, reqDto.getUserId()); + + for(NimsApiDto.DsuseRptInfo item : concurrentList){ + if(item.getOrgUsrRptIdNo().equals(dto.getOrgUsrRptIdNo()) + && item.getUsrRptIdNo().equals(dto.getRefUsrRptIdNo())){ + concurrentList.remove(item); + concurrentList.add(dto); + } + } + } + return new ArrayList<>(concurrentList); + } + + /** + * + * @param reqDto NimsApiRequest.DsuseRptInfoReq + * @param isConfirmed "확인" 상태의 데이타 조회 여부 + * @return List + */ + private List findNimsDsuseRptsOfApi(NimsApiRequest.DsuseRptInfoReq reqDto, boolean isConfirmed) { + List nimsList = new ArrayList<>(); + + while(true) { + NimsApiResult.Response rslt = infNimsService.getDsuseRptInfo(reqDto); + List curList = rslt.getResultOrThrow(); + + if(isEmpty(curList)) break; + + // FIXME: 2024-06-28 데이타 검증후 fix + // 사용자보고번호가 있는 경우 또는 상태가 "확인"이 아니 경우만 추가 + nimsList.addAll( + curList.stream() + //.filter(d -> !RPT_TY_CD.CANCEL.getCode().equals(d.getRptTyCd())) + .filter(d -> isConfirmed || !"확인".equals(d.getStatus())) + .toList() + ); + + if(rslt.isEndYn()) break; + reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); + } + nimsList.forEach(d -> d.setRptTyNm(RPT_TY_CD.getName(d.getRptTyCd()))); + nimsList.sort((a, b) -> a.getUsrRptIdNo().compareTo(b.getUsrRptIdNo())); + return nimsList; + } + + /** + *
+     * tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 생성
+     * 0) 부가 정보 set
+     * 1) 원사용자보고식별번호 set
+     * 2) 데이타 생성
+     *   - 취소인 경우는 tb_dsuse_rpt_info의 사용 여부 'N'으로 생성
+     *
+     * @param dto NimsApiDto.DsuseRptInfo
+     * 
+ */ + private void createDsuseRpt(final NimsApiDto.DsuseRptInfo dto, String userId) { + dto.setRgtr(userId); + dto.setRptTyNm(RPT_TY_CD.getName(dto.getRptTyCd())); + dto.setDsuseSeNm(Constants.DSUSE_SE_CD.getName(dto.getDsuseSeCd())); + dto.setDsusePrvNm(Constants.DSUSE_PRV_CD.getName(dto.getDsusePrvCd())); + dto.setDsuseMthNm(Constants.DSUSE_MTH_CD.getName(dto.getDsuseMthCd())); + + // 참조사용자보고번호가 없으면 -> 원사용자보고식별번호 = 사용자보고식별번호 + if(isEmpty(dto.getRefUsrRptIdNo())){ + dto.setOrgUsrRptIdNo(dto.getUsrRptIdNo()); + }else{ + // FIXME: 2024-06-17 참조사용자보고번호와 사용자보고식별번호가 같으면 skip + // 참조사용자보고번호와 사용자보고식별번호가 같으면 -> 원사용자보고식별번호 = 사용자보고식별번호 + if(dto.getRefUsrRptIdNo().equals(dto.getUsrRptIdNo())){ + dto.setOrgUsrRptIdNo(dto.getUsrRptIdNo()); + }else { + // 참조사용자보고번호가 있으면, 원사용자보고식별번호 조회 + findRecusiveOrgUsrRptIdNo(dto); + } + } + + if (bizNimsMapper.insertDsuseRptInfo(dto) == 1) { + + int dtlCnt = 0; + for (NimsApiDto.DsuseRptInfoDtl d : dto.getListDtl()) { + d.setRgtr(userId); + dtlCnt = dtlCnt + bizNimsMapper.insertDsuseRptInfoDtl(d); + } + if (dto.getRndDtlRptCnt() != dtlCnt) + throw ApiCustomException.create("폐기 정보 상세 등록 실패"); + } else { + throw ApiCustomException.create("폐기 정보 등록 실패"); + } + } + + /** + *
+     * 취소 또는 변경(rptTyCd : 1, 2)시 원사용자보고식별번호 조회 및 설정
+     * 참조사용자보고식별번호 필수
+     * => 사용자보고식별번호 = 참조사용자식별번호 조건 으로 조회
+     * => 조회결과 참조사용자식별번호가 존재하지 않을때 까지 반복 조회(신규(rptTyCd : 0)인 경우 까지)
+     * => 사용자보고식별번호를 원사용자보고식별번호로 설정
+     * @param dto NIMS 폐기보고 데이타(NimsApiDto.DsuseRptInfo)
+     * 
+ */ + private void findRecusiveOrgUsrRptIdNo(NimsApiDto.DsuseRptInfo dto) { + // 원 사용자 식별 번호 set - 변경/취소 인 경우 + // 신규인 경우는 사용자보고식별번호로 설정 + String refUsrRptIdNo = dto.getRefUsrRptIdNo(); + + // 참조사용자보고식별번호로 원사용자보고식별번호조회 + while(true) { + Map map = bizNimsMapper.recusiveRefUsrRptIdNo(refUsrRptIdNo); + if(map == null){ + // 참조사용자식별번호가 없는 경우도 있어(NIMS보고상태 "확인"이 아닌 경우에) skip + //dto.setOrgUsrRptIdNo(dto.getRefUsrRptIdNo()); + //throw ApiCustomException.create("데이타 오류[참조사용자로 사용자보고식별번호 조회 실패 - 데이타 누락]"); + log.error("데이타 오류[참조사용자로 사용자보고식별번호 조회 실패 - 데이타 누락]"); + break; + } + + // 참조사용자보고식별번호가 있으면 계속 조회 + if(!isEmpty(map.get("refUsrRptIdNo"))){ + refUsrRptIdNo = map.get("refUsrRptIdNo"); + continue; + } + + // 참조사용자보고식별번호가 없으면 -> 원사용자보고식별번호 = 사용자보고식별번호로 설정 + dto.setOrgUsrRptIdNo(map.get("usrRptIdNo")); + break; + } + } + + /** + *
+     * - tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl
+     *   사용자보고식별번호 = 참조사용자보고식별번호 인 데이타
+     *   => tb_dsuse_rpt_info, tb_dsuse_rpt_info_dtl 사용여부 'N' update
+     * - tb_dsuse_mgt
+     *   폐기 관리 테이블에 사용자보고식별번호 반영
+     *   => 취소인 경우는 사용자/원사용자 식별번호 clear
+     *   => 변경인 경우는 사용자보고식별번호 -> 참조사용자보고식별번호 update
+     * @param dto NimsApiDto.DsuseRptInfo
+     * 
+ */ + private void updateDsuseRptOfCancel(NimsApiDto.DsuseRptInfo dto, String userId) { + dto.setRgtr(userId); + String errMsg; + if (RPT_TY_CD.CANCEL.getCode().equals(dto.getRptTyCd())) errMsg = RPT_TY_CD.CANCEL.getNm(); + else errMsg = RPT_TY_CD.MODIFY.getNm(); + + if (bizNimsMapper.updateCancelDsuseRptInfo(dto) == 1) { + int cnt = bizNimsMapper.updateCancelDsuseRptInfoDtl(dto); + + } else { + // FIXME: 2024-06-17 실패시 처리 방안 확인 필요?? + log.error("폐기 정보 {} 실패", errMsg); + //throw ApiCustomException.create(String.format("폐기 정보 %s 실패", errMsg)); + } + } + + /** + *
+     * 상품정보에 제조번호 목록 추가
+     * @param list List
+     * @param apiKey Api Key
+     * 
+ */ + private void productInfoaddMnfSeqs(final List list, final String bsshCd, final String apiKey) { + String productCd = ""; + + try { for (NimsApiDto.ProductInfoKd d : list) { productCd = d.getPrductCd(); - List mnfList = getMnfSeqInfo2( + List mnfList = getMnfSeqInfoAll( NimsApiRequest.MnfSeqInfoReq.builder() - .k(apiKey) + .k(apiKey) .fg("1") .pg("1") .p(d.getPrductCd()) - .userId("") + .bc(bsshCd) + .userId("") .build() ); d.getMnfSeqInfos().addAll(mnfList); } }catch (Exception e){ - if( e instanceof ApiCustomException){ - throw ApiCustomException.create(String.format("[%s]의 제조번호 정보를 찾을수 없습니다.", productCd)); - } - throw ApiCustomException.create(e.getMessage()); - } - } - - /** - *
-	 * 폐기관리 상세 등록
-	 * @param reqDto
-	 * @param dtls
-	 * @param files
-	 * 
- */ - private void saveDsuseMgtDtls(BizNimsRequest.DsuseMgtReceiptReq reqDto, List dtls, List files) { - int dtlCnt = 0; - - for (BizNimsDto.DsuseMgtDtl d : dtls) { - String sn = StringUtils.leftPad(dtlCnt + 1 + "", 3, "0"); - d.setDscdmngId(reqDto.getDscdmngId()); - d.setDscdmngSn(sn); - d.setRgtr(reqDto.getUserId()); - dtlCnt = dtlCnt + bizNimsMapper.insertDsuseMgtDtl(d); - - d.setFileId( - uploadFileDeleteAndSave(Constants.FILE_INF_TYPE.DSUSE_PRD_IMG.getCode(), reqDto.getDscdmngId(), - sn, files.get(dtlCnt - 1))); - } - if (dtls.size() != dtlCnt) - throw ApiCustomException.create("폐기 관리 상세 등록 실패"); - } - - - /** - *
-	 * file 저장 처리
-	 * @param infType : 파일 정보 타입 : Constants.FILE_INFO_TYPE
-	 * @param infKey : 파일 정보 키 - 폐기관리ID
-	 * @param subType : 파일 정보 서브 타입
-	 *                  -> 폐기제품이미지 : 폐기관리상세의 순번
-	 *                  -> 폐기이미지 : 이미지 순서
-	 * @param mf	: MultipartFile
-	 * @return fileId
-	 * 
- */ - private String uploadFileDeleteAndSave(String infType, String infKey, String subType, MultipartFile mf) { - Map map = Map.of("infType", infType, "infKey", infKey, "subType", subType); - String[] fileIds = bizNimsMapper.selectFileId(map); - if(fileIds.length > 0){ - fileService.delete(fileIds); - } - // DB 파일 정보 삭제 - bizNimsMapper.deleteFileInfo(map); - - return uploadFileSave(infType, infKey, subType, mf); - } - - /** - *
-	 * file 저장 처리
-	 * @param infType : 파일 정보 타입 : Constants.FILE_INFO_TYPE
-	 * @param infKey : 파일 정보 키 - 폐기관리ID
-	 * @param subType : 파일 정보 서브 타입
-	 *                  -> 폐기제품이미지 : 폐기관리상세의 순번
-	 *                  -> 폐기이미지 : 이미지 순서
-	 * @param mf	: MultipartFile
-	 * @return fileId
-	 * 
- */ - private String uploadFileSave(String infType, String infKey, String subType, MultipartFile mf) { - MultipartFile[] uploads = Collections.singletonList(mf).toArray(new MultipartFile[0]); - List files = (new FileInfoFactory()).makeFileInfos((new FileInfo.Relation()).setInfoType(infType).setInfoKey(infKey).setSubType(subType), uploads); - fileService.create(files); - - return files.get(0).getId(); - } + if( e instanceof ApiCustomException){ + throw ApiCustomException.create(String.format("[%s]의 제조번호 정보를 찾을수 없습니다.", productCd)); + } + throw ApiCustomException.create(e.getMessage()); + } + } + + /** + *
+     * 폐기관리 상세 등록
+     * @param reqDto
+     * @param dtls
+     * @param files
+     * 
+ */ + private void saveDsuseMgtDtls(BizNimsRequest.DsuseMgtReceiptReq reqDto, List dtls, List files) { + int dtlCnt = 0; + + for (BizNimsDto.DsuseMgtDtl d : dtls) { + String sn = StringUtils.leftPad(dtlCnt + 1 + "", 3, "0"); + d.setDscdmngId(reqDto.getDscdmngId()); + d.setDscdmngSn(sn); + d.setRgtr(reqDto.getUserId()); + dtlCnt = dtlCnt + bizNimsMapper.insertDsuseMgtDtl(d); + + d.setFileId( + uploadFileDeleteAndSave(Constants.FILE_INF_TYPE.DSUSE_PRD_IMG.getCode(), reqDto.getDscdmngId(), + sn, files.get(dtlCnt - 1))); + } + if (dtls.size() != dtlCnt) + throw ApiCustomException.create("폐기 관리 상세 등록 실패"); + } + + + /** + *
+     * file 저장 처리
+     * @param infType : 파일 정보 타입 : Constants.FILE_INFO_TYPE
+     * @param infKey : 파일 정보 키 - 폐기관리ID
+     * @param subType : 파일 정보 서브 타입
+     *                  -> 폐기제품이미지 : 폐기관리상세의 순번
+     *                  -> 폐기이미지 : 이미지 순서
+     * @param mf	: MultipartFile
+     * @return fileId
+     * 
+ */ + private String uploadFileDeleteAndSave(String infType, String infKey, String subType, MultipartFile mf) { + Map map = Map.of("infType", infType, "infKey", infKey, "subType", subType); + String[] fileIds = bizNimsMapper.selectFileId(map); + if(fileIds.length > 0){ + fileService.delete(fileIds); + } + // DB 파일 정보 삭제 + bizNimsMapper.deleteFileInfo(map); + + return uploadFileSave(infType, infKey, subType, mf); + } + + /** + *
+     * file 저장 처리
+     * @param infType : 파일 정보 타입 : Constants.FILE_INFO_TYPE
+     * @param infKey : 파일 정보 키 - 폐기관리ID
+     * @param subType : 파일 정보 서브 타입
+     *                  -> 폐기제품이미지 : 폐기관리상세의 순번
+     *                  -> 폐기이미지 : 이미지 순서
+     * @param mf	: MultipartFile
+     * @return fileId
+     * 
+ */ + private String uploadFileSave(String infType, String infKey, String subType, MultipartFile mf) { + MultipartFile[] uploads = Collections.singletonList(mf).toArray(new MultipartFile[0]); + List files = (new FileInfoFactory()).makeFileInfos((new FileInfo.Relation()).setInfoType(infType).setInfoKey(infKey).setSubType(subType), uploads); + fileService.create(files); + + return files.get(0).getId(); + } + + private List getMnfSeqInfoAll(NimsApiRequest.MnfSeqInfoReq reqDto) { + if(isEmpty(reqDto.getK())){ + reqDto.setK(getApiInfInfo(reqDto.getUserId()).get("apiKey")); + } + //reqDto.setFg("1"); // 제조번호 또는 일련번호 구분(1-제조번호, 2-일련번호, 3-바코드/RFID) + reqDto.setPg("1"); // 조회페이지 + + // 시리얼번호 및 제조번호 기준 검색후, 결과내에서 유효기간으로 필터링 하도록 처리 + boolean isPrdValidDe = !isEmpty(reqDto.getT()) && !isEmpty(reqDto.getVd()); + List list = new ArrayList<>(); + while (true) { + NimsApiResult.Response rslt = infNimsService.getMnfSeqInfo(reqDto); + + List curList = rslt.getResult(); + + if (isEmpty(curList)) break; + + if(isPrdValidDe) { + for (NimsApiDto.MnfSeqInfo d : curList) { + if(!isEmpty(d.getPrdValidDe()) && d.getPrdValidDe().contains(reqDto.getVd())){ + list.add(d); + } + } + }else { + list.addAll(curList); + // 올림 차순 정렬 + list.sort((a, b) -> { + if (isEmpty(a.getPrdValidDe()) && isEmpty(b.getPrdValidDe())) + return 0; + if (isEmpty(a.getPrdValidDe())) + return -1; + if (isEmpty(b.getPrdValidDe())) + return 1; + return a.getPrdValidDe().compareTo(b.getPrdValidDe()); + }); + } + // 데이타 조회 결과 마지막 페이지 이거나 100건 이상인 경우 종료 + if(rslt.isEndYn() || list.size() > 100 || isPrdValidDe) break; + + reqDto.setPg(String.valueOf(Integer.parseInt(reqDto.getPg()) + 1)); + } + return list; + } } diff --git a/src/main/java/cokr/xit/adds/biz/nims/web/BizNimsController.java b/src/main/java/cokr/xit/adds/biz/nims/web/BizNimsController.java index 343cec9..b694a60 100644 --- a/src/main/java/cokr/xit/adds/biz/nims/web/BizNimsController.java +++ b/src/main/java/cokr/xit/adds/biz/nims/web/BizNimsController.java @@ -1,36 +1,26 @@ package cokr.xit.adds.biz.nims.web; -import java.util.List; +import java.util.*; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.*; -import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.core.type.*; -import cokr.xit.adds.biz.nims.model.BizNimsDto; -import cokr.xit.adds.biz.nims.model.BizNimsRequest; -import cokr.xit.adds.biz.nims.model.BizNimsResponse; -import cokr.xit.adds.biz.nims.service.BizNimsService; -import cokr.xit.adds.core.model.ApiBaseResponse; -import cokr.xit.adds.core.util.XingUtils; -import cokr.xit.adds.inf.nims.model.NimsApiDto; -import cokr.xit.adds.inf.nims.model.NimsApiRequest; -import cokr.xit.foundation.data.JSON; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.ExampleObject; -import lombok.RequiredArgsConstructor; +import cokr.xit.adds.biz.nims.model.*; +import cokr.xit.adds.biz.nims.service.*; +import cokr.xit.adds.core.model.*; +import cokr.xit.adds.core.util.*; +import cokr.xit.adds.inf.nims.model.*; +import cokr.xit.foundation.data.*; +import io.swagger.v3.oas.annotations.*; +import io.swagger.v3.oas.annotations.media.*; +import lombok.*; /** *
- * description : 
+ * description :
  *
  * packageName : cokr.xit.adds.inf.nims.web
  * fileName    : InfNimsController
@@ -58,7 +48,15 @@ public class BizNimsController {
     public ApiBaseResponse> getNimsBsshInfoSt(
         @ModelAttribute NimsApiRequest.BsshInfoReq dto
     ) {
-        return ApiBaseResponse.of(bizNimsService.saveBsshInfoSt(dto));
+        return bizNimsService.getBsshInfoSt(dto);
+    }
+
+    @Operation(summary = "NIMS 마약류 취급자 정보 조회(취급자코드로)", description = "마약류 취급자 정보 조회(취급자코드로)
NIMS API 호출 결과를 DB에 저장후 결과 Return

아래 항목만 set
bc - 취급자식별번호
userId - 사용자ID
bc 필수", tags = { "NIMS API" }) + @RequestMapping(value = "/saveBsshInfoStQueryBsshInfoByBsshCd", method = { RequestMethod.POST, RequestMethod.GET }) + public ApiBaseResponse> saveBsshInfoStQueryBsshInfoByBsshCd( + @ModelAttribute NimsApiRequest.BsshInfoReq dto + ) { + return ApiBaseResponse.of(bizNimsService.saveBsshInfoStQueryBsshInfoByBsshCd(dto)); } @Operation(summary = "NIMS 마약류 제품 조회", description = "마약류 제품 조회
NIMS API 호출 결과를 DB에 저장후 결과 Return

아래 항목만 set
p - 제품번호
pn - 제품명
dbSkipYn - N:db조회후 결과 없는경우만 API호출, Y:API 호출
userId - 사용자ID
p, pn중 하나는 필수", tags = { "NIMS API" }) @@ -66,7 +64,7 @@ public class BizNimsController { public ApiBaseResponse> getNimsMnfSeqInfo( @ModelAttribute NimsApiRequest.ProductInfoReq dto ) { - return ApiBaseResponse.of(bizNimsService.saveProductInfoKd(dto, false)); + return bizNimsService.getProductInfoKd(dto, false); } @Operation(summary = "NIMS 마약류 상품 정보 & 제조번호 조회", description = "마약류 상품정보 & 제조번호 조회
NIMS API 호출 결과를 DB에 저장후 결과 Return

아래 항목만 set
p - 제품번호
pn - 제품명
dbSkipYn - N:db조회후 결과 없는경우만 API호출, Y:API 호출
userId - 사용자ID
p, pn중 하나는 필수", tags = { "NIMS API" }) @@ -74,7 +72,7 @@ public class BizNimsController { public ApiBaseResponse> getNimsProductInfoKdAndMnfSeqInfo( @ModelAttribute NimsApiRequest.ProductInfoReq dto ) { - return ApiBaseResponse.of(bizNimsService.saveProductInfoKd(dto, true)); + return bizNimsService.getProductInfoKd(dto, true); } @Operation(summary = "NIMS 제조 일련 번호 정보 조회", description = "제보 일련 번호 정보 조회
NIMS API 호출 결과 Return

아래 항목만 set
p - 제품번호
userId - 사용자ID", tags = { "NIMS API" }) @@ -85,13 +83,13 @@ public class BizNimsController { return bizNimsService.getMnfSeqInfo(dto); } - @Operation(summary = "NIMS 제조 일련 번호 정보 조회", description = "제보 일련 번호 정보 조회
NIMS API 호출 결과 Return

아래 항목만 set
p - 제품번호
userId - 사용자ID", tags = { "NIMS API" }) - @RequestMapping(value = "/getNimsMnfSeqInfo2", method = { RequestMethod.POST, RequestMethod.GET }) - public ApiBaseResponse> getNimsMnfSeqInfo2( - @ModelAttribute NimsApiRequest.MnfSeqInfoReq dto - ) { - return ApiBaseResponse.of(bizNimsService.getMnfSeqInfo2(dto)); - } + // @Operation(summary = "NIMS 제조 일련 번호 정보 조회", description = "제보 일련 번호 정보 조회
NIMS API 호출 결과 Return

아래 항목만 set
p - 제품번호
userId - 사용자ID", tags = { "NIMS API" }) + // @RequestMapping(value = "/getNimsMnfSeqInfo2", method = { RequestMethod.POST, RequestMethod.GET }) + // public ApiBaseResponse> getNimsMnfSeqInfo2( + // @ModelAttribute NimsApiRequest.MnfSeqInfoReq dto + // ) { + // return ApiBaseResponse.of(bizNimsService.getMnfSeqInfo2(dto)); + // } @Operation(summary = "NIMS 관할 허가 관청 정보 조회", description = "관할 허가 관청 정보 조회

NIMS API 호출 결과를 DB에 저장후 결과 Return

아래 항목만 set
onm - 기관명
ocd - 기관코드
adr - 주소
dbSkipYn - N : db조회후 결과 없는경우만 API호출, Y : API 호출
userId - 사용자ID
onm, ocd, adr중 하나는 필수", tags = { "NIMS API" }) @RequestMapping(value = "/getNimsJurisdictionGovInfo", method = { RequestMethod.POST, RequestMethod.GET }) @@ -128,9 +126,11 @@ public class BizNimsController { @RequestParam(value = "dsusePrdImgFiles", required = false) List dsusePrdImgFiles ) { JSON json = new JSON(); + NimsApiDto.BsshInfoSt bsshInfoSt = json.parse(dsuseMgtJsonStr, new TypeReference<>() {}); BizNimsRequest.DsuseMgtReceiptReq receiptDto = json.parse(dsuseMgtJsonStr, new TypeReference<>() {}); + List productInfoKds = json.parse(dsuseMgtDtlsJsonStr, new TypeReference<>() {}); List dsuseMgtDtls = json.parse(dsuseMgtDtlsJsonStr, new TypeReference<>() {}); - return ApiBaseResponse.of(bizNimsService.saveDsuseMgtReceipt(receiptDto, dsuseMgtDtls, dsusePrdImgFiles)); + return ApiBaseResponse.of(bizNimsService.saveDsuseMgtReceipt(receiptDto, dsuseMgtDtls, dsusePrdImgFiles, bsshInfoSt, productInfoKds)); } @Operation(summary = "사고 마약류 폐기 관리 폐기 신청서 마스터 정보 변경", description = "사고 마약류 폐기 관리 폐기 신청서 접수 마스터 정보 변경", tags = { "BIZ API" }) diff --git a/src/main/java/cokr/xit/adds/inf/mois/service/bean/InfMoisServiceBean.java b/src/main/java/cokr/xit/adds/inf/mois/service/bean/InfMoisServiceBean.java index f6cd290..3f42547 100644 --- a/src/main/java/cokr/xit/adds/inf/mois/service/bean/InfMoisServiceBean.java +++ b/src/main/java/cokr/xit/adds/inf/mois/service/bean/InfMoisServiceBean.java @@ -1,63 +1,36 @@ package cokr.xit.adds.inf.mois.service.bean; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringReader; -import java.io.UnsupportedEncodingException; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.apache.commons.lang3.StringUtils; +import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.util.*; + +import javax.xml.parsers.*; +import javax.xml.transform.*; +import javax.xml.transform.dom.*; +import javax.xml.transform.stream.*; + +import org.apache.commons.lang3.*; import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; -import org.w3c.dom.Attr; -import org.w3c.dom.DOMException; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -import cokr.xit.adds.biz.nims.service.BizNimsService; -import cokr.xit.adds.core.Constants; -import cokr.xit.adds.core.spring.exception.ApiCustomException; -import cokr.xit.adds.core.util.DateUtils; -import cokr.xit.adds.inf.mois.model.MoisExchangeRequest; -import cokr.xit.adds.inf.mois.model.PackDto; -import cokr.xit.adds.inf.mois.service.InfMoisService; -import cokr.xit.adds.inf.nims.model.NimsApiDto; -import cokr.xit.adds.inf.nims.model.NimsApiRequest; -import cokr.xit.foundation.component.AbstractServiceBean; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.*; +import org.springframework.web.multipart.*; +import org.w3c.dom.*; +import org.xml.sax.*; + +import cokr.xit.adds.biz.nims.service.*; +import cokr.xit.adds.core.*; +import cokr.xit.adds.core.spring.exception.*; +import cokr.xit.adds.core.util.*; +import cokr.xit.adds.inf.mois.model.*; +import cokr.xit.adds.inf.mois.service.*; +import cokr.xit.adds.inf.nims.model.*; +import cokr.xit.foundation.component.*; +import lombok.*; +import lombok.extern.slf4j.*; /** *
- * description : 
+ * description :
  * packageName : cokr.xit.adds.inf.mois.service.bean
  * fileName    : InfMoisServiceBean
  * author      : limju
@@ -343,7 +316,7 @@ public class InfMoisServiceBean extends AbstractServiceBean implements InfMoisSe
     }
 
     private NimsApiDto.BsshInfoSt getBsshInfo(MoisExchangeRequest reqDto) {
-        List list = bizNimsService.saveBsshInfoSt(
+        List list = bizNimsService.saveBsshInfoStQueryBsshInfoByBsshCd(
             NimsApiRequest.BsshInfoReq.builder()
                 .fg("1")
                 .pg("1")
diff --git a/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiDto.java b/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiDto.java
index 4c3274d..5c0b10b 100644
--- a/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiDto.java
+++ b/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiDto.java
@@ -1,30 +1,21 @@
 package cokr.xit.adds.inf.nims.model;
 
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import javax.validation.Valid;
-
-import com.fasterxml.jackson.annotation.JsonAlias;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.JsonSerializer;
-import com.fasterxml.jackson.databind.SerializerProvider;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-
-import cokr.xit.adds.biz.nims.model.BizNimsDto;
-import cokr.xit.adds.biz.nims.model.BizNimsResponse;
-import cokr.xit.adds.core.Constants;
-import cokr.xit.adds.core.model.AuditDto;
-import cokr.xit.adds.core.spring.exception.ApiCustomException;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-import lombok.experimental.SuperBuilder;
+import java.io.*;
+import java.util.*;
+
+import javax.validation.*;
+
+import com.fasterxml.jackson.annotation.*;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+
+import cokr.xit.adds.biz.nims.model.*;
+import cokr.xit.adds.core.*;
+import cokr.xit.adds.core.model.*;
+import cokr.xit.adds.core.spring.exception.*;
+import lombok.*;
+import lombok.experimental.*;
 
 /**
  * 
@@ -210,6 +201,88 @@ public class NimsApiDto {
         private List mnfSeqInfos = new ArrayList<>();
     }
 
+    /**
+     * 상품 정보 저장을 위한 DTO
+     */
+    @Getter
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @SuperBuilder
+    public static class ProductInfoKdSaveDTO extends AuditDto {
+        /**
+         * 품목코드
+         */
+        @JsonAlias("PRDUCT_CD")
+        private String prductCd;
+
+        /**
+         * 제품대표코드
+         */
+        @JsonAlias("PRDLST_MST_CD")
+        private String prdlstMstCd;
+
+        /**
+         * 제품명
+         */
+        @JsonAlias("PRDUCT_NM")
+        private String prductNm;
+
+        /**
+         * 마약/항정 구분명
+         */
+        @JsonAlias("NRCD_SE_NM")
+        private String nrcdSeNm;
+
+        /**
+         * 중점/일반 구분
+         */
+        @JsonAlias("PRTM_SE_NM")
+        private String prtmSeNm;
+
+        /**
+         * 제품최소유통단위수량
+         * 제품규격정보(고정값 = 1)
+         */
+        @JsonAlias("minDistbQy")
+        private Integer prdMinDistbQy;
+
+        /**
+         * 제품최소유통단위
+         */
+        @JsonAlias("minDistbUnit")
+        private String stdPackngStleNm;
+
+        /**
+         * 제품총낱개단위수량
+         */
+        @JsonAlias("pceQy")
+        private Integer prdTotPceQy;
+
+        /**
+         * 제품낱개단위
+         */
+        @JsonAlias("pceUnit")
+        private String pceCoUnitNm;
+
+        /**
+         * 마약류취급자식별번호
+         */
+        @JsonAlias("BSSH_CD")
+        private String bsshCd;
+
+        /**
+         * 등록일
+         */
+        @JsonAlias("RGS_DT")
+        private String rgsDt;
+
+        /**
+         * 변경일
+         */
+        @JsonAlias("UPD_DT")
+        private String updDt;;
+    }
+
     /**
      * 제품 제조 일련 번호 정보 조회 response
      */
@@ -497,9 +570,10 @@ public class NimsApiDto {
                             && Objects.equals(
                                 Objects.toString(rptDtl.getPrdValidDe(), "").replaceAll("-", ""),
                                 Objects.toString(mgtDtl.getPrdValidDe(), "").replaceAll("-", ""))
-                            && Objects.equals(
-                                Objects.toString(rptDtl.getMnfSeq(), "").replaceAll("-", ""),
-                                Objects.toString(mgtDtl.getMnfSeq(), "").replaceAll("-", ""))
+                            // FIXME:: NIMS 데이타 일치여부 체크 - 제조번호 제외
+                            // && Objects.equals(
+                            //     Objects.toString(rptDtl.getMnfSeq(), "").replaceAll("-", ""),
+                            //     Objects.toString(mgtDtl.getMnfSeq(), "").replaceAll("-", ""))
                             && Objects.equals(rptDtl.getDsuseQy(), mgtDtl.getDsuseQy())) {
                             rptDtl.setMatchYn("Y");
                             break;
@@ -678,4 +752,3 @@ public class NimsApiDto {
         private String bassDtlAdres;
     }
 }
-
diff --git a/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiRequest.java b/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiRequest.java
index 4386160..c52c558 100644
--- a/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiRequest.java
+++ b/src/main/java/cokr/xit/adds/inf/nims/model/NimsApiRequest.java
@@ -2,17 +2,13 @@ package cokr.xit.adds.inf.nims.model;
 
 import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.*;
 
-import javax.validation.constraints.NotEmpty;
-import javax.validation.constraints.Pattern;
+import javax.validation.constraints.*;
 
-import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.*;
 
-import cokr.xit.adds.core.Constants;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import cokr.xit.adds.core.*;
+import io.swagger.v3.oas.annotations.media.*;
+import lombok.*;
 
 /**
  * 
@@ -114,9 +110,9 @@ public class NimsApiRequest {
          * true 인 경우 DB 조회 skip
          * 
*/ - @Schema(title = "DB 조회 skip 여부", description = "DB 조회 skip 여부(DB 조회 없이 NIMS API호출 하려면 Y)", example = "N") - @Builder.Default - private String dbSkipYn = "N"; + // @Schema(title = "DB 조회 skip 여부", description = "DB 조회 skip 여부(DB 조회 없이 NIMS API호출 하려면 Y)", example = "N") + // @Builder.Default + // private String dbSkipYn = "N"; /** *
@@ -198,15 +194,11 @@ public class NimsApiRequest {
 
         /**
          * 
-         * DB 조회 skip 여부
-         * DB먼저 조회 하고 없는 경우 NIMS API 조회 호출
-         * true 인 경우 DB 조회 skip
-         * 업무상 필요에 의해 추가
+         * 마약류취급자번호
          * 
*/ - @Schema(title = "DB 조회 skip 여부", description = "DB 조회 skip 여부(DB 조회 없이 NIMS API호출 하려면 Y)", example = "N") - @Builder.Default - private String dbSkipYn = "N"; + @Schema(title = "마약류취급자번호", description = "마약류취급자번호", example = " ") + private String bc; /** *
@@ -384,11 +376,17 @@ public class NimsApiRequest {
         @Pattern(regexp = "^$|[A-Z0-9]{1,}", message = "번호는 영숫자(A~Z, 0~9)만 입력가능합니다")
         private String t = StringUtils.EMPTY;
 
+        /**
+         * 마약류 취급자 식별 번호
+         */
+        @Schema(title = "마약류 취급자 식별 번호", description = "마약류 취급자 식별 번호", example = " ")
+        private String bc;
+
         /**
          * 유효기간
          */
         @Schema(title = "유효기간", description = "유효기간", example = " ")
-        private String prdValidDe;
+        private String vd;
 
         /**
          * 
diff --git a/src/main/java/cokr/xit/adds/inf/nims/service/bean/InfNimsServiceBean.java b/src/main/java/cokr/xit/adds/inf/nims/service/bean/InfNimsServiceBean.java
index 7b6cad6..2778c7f 100644
--- a/src/main/java/cokr/xit/adds/inf/nims/service/bean/InfNimsServiceBean.java
+++ b/src/main/java/cokr/xit/adds/inf/nims/service/bean/InfNimsServiceBean.java
@@ -1,27 +1,24 @@
 package cokr.xit.adds.inf.nims.service.bean;
 
-import javax.validation.Validation;
-import javax.validation.Validator;
+import javax.validation.*;
 
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
+import org.springframework.stereotype.*;
 
-import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.core.type.*;
 
-import cokr.xit.adds.core.spring.exception.ApiCustomException;
-import cokr.xit.adds.core.util.ApiUtil;
-import cokr.xit.adds.inf.nims.model.NimsApiDto;
-import cokr.xit.adds.inf.nims.model.NimsApiRequest;
-import cokr.xit.adds.inf.nims.model.NimsApiResult;
-import cokr.xit.adds.inf.nims.service.InfNimsService;
-import cokr.xit.foundation.component.AbstractServiceBean;
-import cokr.xit.foundation.data.JSON;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
+import cokr.xit.adds.core.spring.exception.*;
+import cokr.xit.adds.core.util.*;
+import cokr.xit.adds.inf.nims.model.*;
+import cokr.xit.adds.inf.nims.service.*;
+import cokr.xit.foundation.component.*;
+import cokr.xit.foundation.data.*;
+import lombok.*;
+import lombok.extern.slf4j.*;
 
 /**
  * 
- * description : 
+ * description :
  *
  * packageName : cokr.xit.adds.inf.nims.service.bean
  * fileName    : InfNimsServiceBean
@@ -57,7 +54,7 @@ public class InfNimsServiceBean extends AbstractServiceBean implements InfNimsSe
 	private String productinfoKd;
 
 	/**
-	 * 마약류 제품 제조번호 정보 조회 API URL
+	 * 업체별 마약류 제품 제조번호 정보 조회 API URL
 	 */
 	@Value("${app.inf.nims.api.seqinfo}")
 	private String seqinfo;
@@ -95,13 +92,18 @@ public class InfNimsServiceBean extends AbstractServiceBean implements InfNimsSe
 		ApiUtil.validate(dto, null, validator);
 		if(!isEmpty(dto.getYmd())) ApiUtil.checkYmdError(dto.getYmd(), null);
 
+		//FIXME: 운영기 반영 이후 주석 제거
 		String rslt = ApiUtil.callNimsApi(nimsUrl + productinfoKd, dto);
 		NimsApiResult result = json.parse(rslt, new TypeReference<>() {});
 		return result.getResponse();
 	}
 
+	/**
+	 * 업체별 상품일련번호 정보 조회 API URL
+	 * @param dto NimsApiRequest.MnfSeqInfoReq
+	 * @return NimsApiResult.Response
+	 */
 	@Override
-	//@TraceLogging
 	public NimsApiResult.Response getMnfSeqInfo(NimsApiRequest.MnfSeqInfoReq dto) {
 		ApiUtil.validate(dto, null, validator);
 		if(!isEmpty(dto.getYmd())) ApiUtil.checkYmdError(dto.getYmd(), null);
diff --git a/src/main/java/cokr/xit/adds/inf/nims/web/InfNimsController.java b/src/main/java/cokr/xit/adds/inf/nims/web/InfNimsController.java
index 345c4c7..c2dab5c 100644
--- a/src/main/java/cokr/xit/adds/inf/nims/web/InfNimsController.java
+++ b/src/main/java/cokr/xit/adds/inf/nims/web/InfNimsController.java
@@ -52,7 +52,7 @@ public class InfNimsController {
 		return ApiBaseResponse.of(infNimsService.getProductInfoKd(dto));
 	}
 
-	@Operation(summary = "제조 일련 번호 정보 조회", description = "제조 일련 번호 정보 조회")
+	@Operation(summary = "제조 일련 번호 정보 조회(업체별)", description = "제조 일련 번호 정보 조회(업체별)")
 	@PostMapping("/getMnfSeqInfo")
 	public ApiBaseResponse> getMnfSeqInfo(
 		@RequestBody NimsApiRequest.MnfSeqInfoReq dto
diff --git a/src/main/resources/config/application-nims.yml b/src/main/resources/config/application-nims.yml
index f4540b9..263320c 100644
--- a/src/main/resources/config/application-nims.yml
+++ b/src/main/resources/config/application-nims.yml
@@ -4,7 +4,7 @@ app:
       api:
         bsshinfoStV1: /api/bsshinfo_st_v1.do
         productinfoKd: /api/productinfo_kd.do
-        seqinfo: /api/seqinfo.do
+        seqinfo: /api/seqinfo_pub.do
         officeinfo: /api/officeinfo.do
         placeinfoV1: /api/placeinfo_v1.do
         dsuseresult: /api/dsuseresult.do
diff --git a/src/main/resources/sql/mapper/biz/nims-mysql-mapper.xml b/src/main/resources/sql/mapper/biz/nims-mysql-mapper.xml
index bc95265..4405ef6 100644
--- a/src/main/resources/sql/mapper/biz/nims-mysql-mapper.xml
+++ b/src/main/resources/sql/mapper/biz/nims-mysql-mapper.xml
@@ -44,21 +44,21 @@
         )
         ON DUPLICATE KEY UPDATE
             bssh_nm = #{bsshNm},            /* 마약류취급자명 */
-            induty_nm = #{indutyNm},        /* 업종명 */
-            hdnt_cd = #{hdntCd},            /* 의료업자구분 */
-            hdnt_nm = #{hdntNm},            /* 의료업자구분명 */
-            bizrno = #{bizrno},             /* 사업자등록번호 */
-            rprsntv_nm = #{rprsntvNm},      /* 대표자명 */
-            chrg_nm = #{chrgNm},            /* 담당자명 */
-            hptl_no = #{hptlNo},            /* 요약기관번호 */
-            join_yn = #{joinYn},            /* 가입여부 */
-            bssh_stts_nm = #{bsshSttusNm},  /* 마약류취급자상태명 */
-            prmisn_no = #{prmisnNo},        /* 허가번호 */
+            bizrno =  #{bizrno},            /* 사업자등록번호 */
+            rprsntv_nm =  #{rprsntvNm},     /* 대표자명 */
+            prmisn_no =  #{prmisnNo},       /* 허가번호 */
+            induty_nm = CASE WHEN induty_nm != IFNULL(#{indutyNm}, '') AND IFNULL(#{indutyNm}, '') != '' THEN #{indutyNm} ELSE induty_nm END,           /* 업종명 */
+            hdnt_cd =  CASE WHEN hdnt_cd != IFNULL(#{hdntCd}, '') AND IFNULL(#{hdntCd}, '') != '' THEN #{hdntCd} ELSE hdnt_cd END,                      /* 의료업자구분 */
+            hdnt_nm =  CASE WHEN hdnt_nm != IFNULL(#{hdntNm}, '') AND IFNULL(#{hdntNm}, '') != '' THEN #{hdntNm} ELSE hdnt_nm END,                      /* 의료업자구분명 */
+            chrg_nm =  CASE WHEN chrg_nm != IFNULL(#{chrgNm}, '') AND IFNULL(#{chrgNm}, '') != '' THEN #{chrgNm} ELSE chrg_nm END,                      /* 담당자명 */
+            hptl_no =  CASE WHEN hptl_no != IFNULL(#{hptlNo}, '') AND IFNULL(#{hptlNo}, '') != '' THEN #{hptlNo} ELSE hptl_no END,                      /* 요약기관번호 */
+            join_yn =  CASE WHEN join_yn != IFNULL(#{joinYn}, '') AND IFNULL(#{joinYn}, '') != '' THEN #{joinYn} ELSE join_yn END,                      /* 가입여부 */
+            bssh_stts_nm =  CASE WHEN bssh_stts_nm != IFNULL(#{bsshSttusNm}, '') AND IFNULL(#{bsshSttusNm}, '') != '' THEN #{bsshSttusNm} ELSE bssh_stts_nm END,  /* 마약류취급자상태명 */
             mdfcn_dt = DATE_FORMAT(now(), '%Y%m%d%H%i%s'),
             mdfr = #{rgtr}
     
 
-    
+    
         /** nims-mysql-mapper|mergeProductInfoKd-상품정보 생성|julim  */
         INSERT INTO tb_prduct_info(
             prduct_cd,              /* 제품코드 */
@@ -87,24 +87,24 @@
             #{prdTotPceQy},
             #{pceCoUnitNm},
             #{bsshCd},
-            #{rgsDt},
-            #{updDt},
+            NULLIF(#{rgsDt}, ''),
+            NULLIF(#{updDt}, ''),
             'Y',
             DATE_FORMAT(now(), '%Y%m%d%H%i%s'),
             #{rgtr}
         )
         ON DUPLICATE KEY UPDATE
-            prdlst_mst_cd = #{prdlstMstCd},             /* 제품대표코드 */
             prduct_nm = #{prductNm},                    /* 제품명 */
-            nrcd_se_nm = #{nrcdSeNm},                   /* 마약항정구분 */
-            prtm_se_nm = #{prtmSeNm},                   /* 중점일반구분 */
             prd_min_distb_qy = #{prdMinDistbQy},        /* 최소유통단위수량 - 제품규격정보(고정값=1) */
             std_packng_stle_nm = #{stdPackngStleNm},    /* 제품최소유통단위 */
             prd_tot_pce_qy = #{prdTotPceQy},            /* 제품총낱개단위수량 */
             pce_co_unit_nm = #{pceCoUnitNm},            /* 제품낱개단위 */
-            bssh_cd = #{bsshCd},                        /* 마약류취급자식별번호 */
-            rgs_dt = #{rgsDt},                          /* 등록일 */
-            upd_dt = #{updDt},                          /* 변경일 */
+            prdlst_mst_cd = CASE WHEN prdlst_mst_cd != IFNULL(#{prdlstMstCd}, '') AND IFNULL(#{prdlstMstCd}, '') != '' THEN #{prdlstMstCd} ELSE prdlst_mst_cd END,  /* 제품대표코드 */
+            nrcd_se_nm = CASE WHEN nrcd_se_nm != IFNULL(#{nrcdSeNm}, '') AND IFNULL(#{nrcdSeNm}, '') != '' THEN #{nrcdSeNm} ELSE nrcd_se_nm END,                    /* 마약항정구분 */
+            prtm_se_nm = CASE WHEN prtm_se_nm != IFNULL(#{prtmSeNm}, '') AND IFNULL(#{prtmSeNm}, '') != '' THEN #{prtmSeNm} ELSE prtm_se_nm END,                    /* 중점일반구분 */
+            bssh_cd = CASE WHEN bssh_cd != IFNULL(#{bsshCd}, '') AND IFNULL(#{bsshCd}, '') != '' THEN #{bsshCd} ELSE bssh_cd END,                                   /* 마약류취급자식별번호 */
+            rgs_dt = CASE WHEN rgs_dt != NULLIF(#{rgsDt}, '') AND IFNULL(#{rgsDt}, '') != '' THEN NULLIF(#{rgsDt}, '') ELSE rgs_dt END,                             /* 등록일 */
+            upd_dt = CASE WHEN upd_dt != NULLIF(#{updDt}, '') AND IFNULL(#{updDt}, '') != '' THEN NULLIF(#{updDt}, '') ELSE upd_dt END,                             /* 변경일 */
             mdfcn_dt = DATE_FORMAT(now(), '%Y%m%d%H%i%s'),
             mdfr = #{rgtr}
     
@@ -295,6 +295,28 @@
         WHERE dscdmng_id = #{dscdmngId}
     
 
+    
+
+    
+        /** nims-mysql-mapper|updateDsuseLocOfDsuseMgt-폐기관리 결과의 폐기장소 변경|julim  */
+        UPDATE tb_dsuse_mgt
+           SET dsuse_loc = #{dsuseLoc}
+             , mdfcn_dt = DATE_FORMAT(now(), '%Y%m%d%H%i%s')
+             , mdfr = #{rgtr}
+         WHERE use_yn = 'Y'
+           AND dept_cd = (SELECT dept_cd FROM tb_user WHERE user_acnt = #{userId})
+           AND dsuse_mth_cd = #{dsuseMthCd}
+           AND dsuse_se_cd = #{dsuseSeCd}
+           AND dsuse_de = #{dsuseDe}
+           AND tb_dsuse_mgt.dscdmng_id != #{dscdmngId}
+    
+
+
     
         /** nims-mysql-mapper|updateDsuseMgtRslt-폐기관리 정보 변경|julim  */
         UPDATE tb_dsuse_mgt