봄 등록, csv 적용, 모품번 없이 저장 기능 개발, 엑셀 새로 업로드 기능 추가
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package com.pms.service;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.sql.Clob;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -3149,6 +3151,231 @@ public class PartMngService extends BaseService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CSV 파일 파싱 (엑셀과 동일한 형식으로 반환)
|
||||
* 첫 번째 열이 "수준"인 경우 계층 구조를 자동으로 파악
|
||||
*/
|
||||
private ArrayList parsingCsvFile(String path, String fileName, SqlSession sqlSession) throws Exception {
|
||||
ArrayList resultList = new ArrayList();
|
||||
BufferedReader br = null;
|
||||
|
||||
try {
|
||||
File csvFile = new File(path + "\\" + fileName);
|
||||
br = new BufferedReader(new InputStreamReader(new FileInputStream(csvFile), "UTF-8"));
|
||||
|
||||
String line;
|
||||
int rowIndex = 0;
|
||||
|
||||
// 모든 자품번 수집 및 수준별 품번 매핑
|
||||
Set<String> allPartNumbers = new HashSet<>();
|
||||
List<String[]> allRows = new ArrayList<>();
|
||||
Map<String, String> levelToPartNoMap = new HashMap<>(); // 수준 -> 품번 매핑
|
||||
Map<Integer, String> depthToPartNoMap = new HashMap<>(); // 깊이 -> 품번 매핑 (숫자만 있는 경우)
|
||||
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] values = line.split(",");
|
||||
allRows.add(values);
|
||||
|
||||
// 헤더가 아닌 경우 품번 수집
|
||||
if (rowIndex > 0 && values.length > 1) {
|
||||
String level = values[0].trim(); // 수준
|
||||
String partNo = values[1].trim(); // 품번
|
||||
|
||||
// CSV 큰따옴표 제거
|
||||
if (level.startsWith("\"") && level.endsWith("\"") && level.length() > 1) {
|
||||
level = level.substring(1, level.length() - 1);
|
||||
}
|
||||
if (partNo.startsWith("\"") && partNo.endsWith("\"") && partNo.length() > 1) {
|
||||
partNo = partNo.substring(1, partNo.length() - 1);
|
||||
}
|
||||
|
||||
if (!StringUtils.isBlank(partNo)) {
|
||||
allPartNumbers.add(partNo);
|
||||
if (!StringUtils.isBlank(level)) {
|
||||
levelToPartNoMap.put(level, partNo);
|
||||
// 숫자만 있는 경우를 위한 깊이 매핑
|
||||
try {
|
||||
int depth = Integer.parseInt(level);
|
||||
depthToPartNoMap.put(depth, partNo);
|
||||
} catch (NumberFormatException e) {
|
||||
// 숫자가 아니면 무시 (1.1, 1.4.1 같은 형식)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
// 데이터 파싱
|
||||
rowIndex = 0;
|
||||
Map<Integer, String> currentDepthPartNoMap = new HashMap<>(); // 현재 처리 중인 각 깊이별 최신 품번
|
||||
|
||||
for (String[] values : allRows) {
|
||||
if (rowIndex == 0) { // 헤더 건너뛰기
|
||||
rowIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (values.length < 11) { // 최소 11개 컬럼 필요 (수준 포함)
|
||||
rowIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
Map partMap = new HashMap();
|
||||
AtomicInteger emptyColCnt = new AtomicInteger(0);
|
||||
String noteMsg = "";
|
||||
|
||||
int colIndex = 0;
|
||||
|
||||
// 각 컬럼 파싱 (CSV: 수준, 품번, 품명, 수량, ...)
|
||||
String level = getCsvValue(values, colIndex++, emptyColCnt); // 0: 수준
|
||||
String partNo = getCsvValue(values, colIndex++, emptyColCnt); // 1: 품번
|
||||
String partName = getCsvValue(values, colIndex++, emptyColCnt); // 2: 품명
|
||||
String qty = getCsvValue(values, colIndex++, emptyColCnt); // 3: 수량
|
||||
String itemQty = getCsvValue(values, colIndex++, emptyColCnt); // 4: 항목수량
|
||||
String material = getCsvValue(values, colIndex++, emptyColCnt); // 5: 재료
|
||||
String heatTreatmentHardness = getCsvValue(values, colIndex++, emptyColCnt); // 6: 열처리경도
|
||||
String heatTreatmentMethod = getCsvValue(values, colIndex++, emptyColCnt); // 7: 열처리방법
|
||||
String surfaceTreatment = getCsvValue(values, colIndex++, emptyColCnt); // 8: 표면처리
|
||||
String supplier = getCsvValue(values, colIndex++, emptyColCnt); // 9: 공급업체
|
||||
String partType = getCsvValue(values, colIndex++, emptyColCnt); // 10: 범주이름
|
||||
|
||||
// 수준으로부터 부모 품번 찾기
|
||||
String parentPartNo = "";
|
||||
if (!StringUtils.isBlank(level)) {
|
||||
// 숫자만 있는 경우 (1, 2, 3, 4 등)
|
||||
try {
|
||||
int currentDepth = Integer.parseInt(level);
|
||||
|
||||
// 현재 깊이의 품번 저장 (다음 행에서 참조할 수 있도록)
|
||||
if (!StringUtils.isBlank(partNo)) {
|
||||
currentDepthPartNoMap.put(currentDepth, partNo);
|
||||
}
|
||||
|
||||
// 부모 찾기: 바로 이전 깊이의 최신 품번
|
||||
if (currentDepth > 1) {
|
||||
int parentDepth = currentDepth - 1;
|
||||
if (currentDepthPartNoMap.containsKey(parentDepth)) {
|
||||
parentPartNo = currentDepthPartNoMap.get(parentDepth);
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 숫자가 아닌 경우 (1.1, 1.4.1 등) - 기존 로직 사용
|
||||
String parentLevel = getParentLevel(level);
|
||||
if (!StringUtils.isBlank(parentLevel) && levelToPartNoMap.containsKey(parentLevel)) {
|
||||
parentPartNo = levelToPartNoMap.get(parentLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 유효성 검증
|
||||
if(!StringUtils.isBlank(parentPartNo) && rowIndex > 2) {
|
||||
if(!allPartNumbers.contains(parentPartNo)) {
|
||||
noteMsg += "모품번 미존재:" + parentPartNo + ";";
|
||||
}
|
||||
}
|
||||
|
||||
// PART_TYPE 코드 조회
|
||||
String partTypeCode = "";
|
||||
if(!StringUtils.isBlank(partType) && rowIndex > 2) {
|
||||
Map sqlParamMap = new HashMap();
|
||||
sqlParamMap.put("CODE_NAME", partType);
|
||||
String partNoForCheck = CommonUtils.checkNull(partNo);
|
||||
sqlParamMap.put("partNo", partNoForCheck);
|
||||
Map partTypeMap = sqlSession.selectOne("partMng.parttypeInfo", sqlParamMap);
|
||||
if(null != partTypeMap && !StringUtils.isBlank((String)partTypeMap.get("code_id"))){
|
||||
partTypeCode = (String)partTypeMap.get("code_id");
|
||||
} else {
|
||||
noteMsg += "부품유형 확인:" + partType + ";";
|
||||
}
|
||||
} else if(!StringUtils.isBlank(partType) && rowIndex <= 2) {
|
||||
Map sqlParamMap = new HashMap();
|
||||
sqlParamMap.put("CODE_NAME", partType);
|
||||
Map partTypeMap = sqlSession.selectOne("partMng.parttypeInfo", sqlParamMap);
|
||||
if(null != partTypeMap && !StringUtils.isBlank((String)partTypeMap.get("code_id"))){
|
||||
partTypeCode = (String)partTypeMap.get("code_id");
|
||||
}
|
||||
}
|
||||
|
||||
// Map에 데이터 저장
|
||||
partMap.put("LEVEL", level); // 수준 값 (화면 표시용)
|
||||
partMap.put("PARENT_PART_NO", parentPartNo); // 실제 부모 품번 (저장용)
|
||||
partMap.put("PART_NO", partNo);
|
||||
partMap.put("PART_NAME", partName);
|
||||
partMap.put("QTY", qty);
|
||||
partMap.put("ITEM_QTY", itemQty);
|
||||
partMap.put("MATERIAL", material);
|
||||
partMap.put("HEAT_TREATMENT_HARDNESS", heatTreatmentHardness);
|
||||
partMap.put("HEAT_TREATMENT_METHOD", heatTreatmentMethod);
|
||||
partMap.put("SURFACE_TREATMENT", surfaceTreatment);
|
||||
partMap.put("SUPPLIER", supplier);
|
||||
partMap.put("PART_TYPE", partTypeCode);
|
||||
partMap.put("NOTE", noteMsg);
|
||||
|
||||
if(!StringUtils.isBlank(noteMsg) || emptyColCnt.intValue() < 9) {
|
||||
resultList.add(partMap);
|
||||
}
|
||||
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
/**
|
||||
* CSV 값 추출 헬퍼 메서드
|
||||
*/
|
||||
private String getCsvValue(String[] values, int index, AtomicInteger emptyColCnt) {
|
||||
if (index >= values.length) {
|
||||
emptyColCnt.incrementAndGet();
|
||||
return "";
|
||||
}
|
||||
String value = values[index].trim();
|
||||
|
||||
// CSV 큰따옴표 제거
|
||||
if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
|
||||
value = value.substring(1, value.length() - 1);
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(value)) {
|
||||
emptyColCnt.incrementAndGet();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수준으로부터 부모 수준 찾기
|
||||
* 예: "1.4.1" -> "1.4", "1.8" -> "1", "1" -> ""
|
||||
*/
|
||||
private String getParentLevel(String level) {
|
||||
if (StringUtils.isBlank(level)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// 마지막 점(.)의 위치 찾기
|
||||
int lastDotIndex = level.lastIndexOf('.');
|
||||
if (lastDotIndex > 0) {
|
||||
// 마지막 점 이전까지가 부모 수준
|
||||
return level.substring(0, lastDotIndex);
|
||||
}
|
||||
|
||||
// 점이 없으면 최상위 레벨이므로 부모 없음
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* BOM 복사를 위한 데이터 조회 (엑셀 파싱 형식과 동일하게 반환)
|
||||
*/
|
||||
@@ -3250,6 +3477,19 @@ public class PartMngService extends BaseService {
|
||||
String path = CommonUtils.checkNull(fileMap.get("FILE_PATH"));
|
||||
String fileName = CommonUtils.checkNull(fileMap.get("SAVED_FILE_NAME"));
|
||||
|
||||
// CSV 파일인 경우 (수준 기반 계층 구조)
|
||||
if (fileName.endsWith(".csv") || fileName.endsWith(".CSV")) {
|
||||
resultList = parsingCsvFile(path, fileName, sqlSession);
|
||||
// CSV 파일임을 표시
|
||||
for(int i = 0; i < resultList.size(); i++) {
|
||||
Map partMap = (Map)resultList.get(i);
|
||||
partMap.put("IS_CSV", "Y");
|
||||
}
|
||||
sqlSession.close();
|
||||
return resultList;
|
||||
}
|
||||
|
||||
// Excel 파일인 경우
|
||||
FileInputStream fis = new FileInputStream(path+"\\"+fileName);
|
||||
|
||||
Workbook workBook = null;
|
||||
@@ -3983,14 +4223,27 @@ public class PartMngService extends BaseService {
|
||||
SqlSession sqlSession = null;
|
||||
Map sqlMap = new HashMap();
|
||||
try{
|
||||
List<Map<String, Object>> gridDataList = JsonUtil.JsonToList(CommonUtils.checkNull(paramMap.get("jqGrid")));
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
String objid = CommonUtils.checkNull(paramMap.get("importPopObjid"));
|
||||
String bomobjid = CommonUtils.checkNull(paramMap.get("BOM_REPORT_OBJID"));
|
||||
if(!"".equals(bomobjid)){
|
||||
objid = bomobjid;
|
||||
}
|
||||
String masterObjid = objid;
|
||||
List<Map<String, Object>> gridDataList = JsonUtil.JsonToList(CommonUtils.checkNull(paramMap.get("jqGrid")));
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
|
||||
|
||||
// 기존 BOM이 있으면 해당 BOM을 수정, 없으면 새로 생성
|
||||
String objid = CommonUtils.checkNull(paramMap.get("importPopObjid"));
|
||||
String bomobjid = CommonUtils.checkNull(paramMap.get("BOM_REPORT_OBJID"));
|
||||
|
||||
if(!"".equals(bomobjid)){
|
||||
// 기존 BOM 수정: 기존 파트 데이터 삭제
|
||||
objid = bomobjid;
|
||||
Map deleteParam = new HashMap();
|
||||
deleteParam.put("BOM_REPORT_OBJID", objid);
|
||||
sqlSession.delete("partMng.deleteBomPartQtyByBomObjid", deleteParam);
|
||||
|
||||
// BOM 상태 초기화
|
||||
Map resetParam = new HashMap();
|
||||
resetParam.put("OBJID", objid);
|
||||
sqlSession.update("partMng.resetBomReportStatus", resetParam);
|
||||
}
|
||||
|
||||
String masterObjid = objid;
|
||||
|
||||
// BOM부터 만들고 프로젝트에 연결하도록 변경 - 프로젝트 유닛 정보 조회 주석처리
|
||||
/*
|
||||
@@ -4219,8 +4472,10 @@ public class PartMngService extends BaseService {
|
||||
String parent_objid ="";
|
||||
partobjMap.put("PART_NO", CommonUtils.checkNull((String)insertMap.get("PARENT_PART_NO")));
|
||||
partobjMap.put("BOM_REPORT_OBJID", objid);
|
||||
resultMap = (HashMap)sqlSession.selectOne("partMng.getBomPartQtyObjid", partobjMap);
|
||||
if(null!=resultMap){
|
||||
// selectList로 변경 (중복 품번 대응)
|
||||
List<Map> resultList = sqlSession.selectList("partMng.getBomPartQtyObjid", partobjMap);
|
||||
if(resultList != null && resultList.size() > 0){
|
||||
resultMap = (HashMap)resultList.get(0); // 첫 번째 결과 사용
|
||||
parent_objid = CommonUtils.checkNull((String)resultMap.get("child_objid"));
|
||||
}
|
||||
|
||||
@@ -4234,13 +4489,7 @@ public class PartMngService extends BaseService {
|
||||
System.out.println(" insertMap--->"+insertMap);
|
||||
|
||||
//BOM저장
|
||||
//BOM에 구조 추가할경우 상태값 변경
|
||||
if(!"".equals(bomobjid)){
|
||||
insertMap.put("STATUS", "deploy");
|
||||
insertMap.put("LAST_PART_OBJID", part_no);
|
||||
insertMap.put("DEPLOY_USER_ID", "addBom");
|
||||
insertMap.put("DEPLOY_DATE", "Y");
|
||||
}
|
||||
// 기존 BOM 수정 시 deploy 상태는 설정하지 않음 (초기화된 상태 유지)
|
||||
|
||||
sqlSession.insert("partMng.relatePartInfo", insertMap);
|
||||
}//end of gridDataList
|
||||
|
||||
Reference in New Issue
Block a user