Merge origin/main - 생산실적 날짜별 기능 병합

This commit is contained in:
2025-12-23 16:37:51 +09:00
6 changed files with 677 additions and 199 deletions

View File

@@ -1939,4 +1939,60 @@ public class ProductionPlanningController extends BaseService {
return resultMap;
}
/**
* 생산실적 날짜별 조회
*/
@ResponseBody
@RequestMapping("/productionplanning/getProdResultListByDate.do")
public Map getProdResultListByDate(HttpServletRequest request, @RequestParam Map<String, Object> paramMap) {
Map<String, Object> resultMap = new HashMap<String, Object>();
try {
List list = productionPlanningService.getProdResultListByDate(paramMap);
resultMap.put("result", "success");
resultMap.put("list", list);
} catch(Exception e) {
e.printStackTrace();
resultMap.put("result", "fail");
resultMap.put("msg", "조회 실패");
}
return resultMap;
}
/**
* 생산실적 날짜별 저장
*/
@ResponseBody
@RequestMapping(value="/productionplanning/saveProdResultByDate.do", produces="application/json;charset=UTF-8")
public Map saveProdResultByDate(HttpServletRequest request, @RequestBody Map<String, Object> paramMap) {
Map<String, Object> resultMap = new HashMap<String, Object>();
try {
HttpSession session = request.getSession();
PersonBean person = (PersonBean) session.getAttribute(Constants.PERSON_BEAN);
// 세션 정보가 없는 경우 기본값 설정
String userId = "";
String userName = "";
if(person != null) {
userId = person.getUserId();
userName = person.getUserName();
}
paramMap.put("userId", userId);
paramMap.put("userName", userName);
boolean success = productionPlanningService.saveProdResultByDate(paramMap);
if(success) {
resultMap.put("result", "success");
resultMap.put("msg", "저장되었습니다.");
} else {
resultMap.put("result", "fail");
resultMap.put("msg", "저장에 실패했습니다.");
}
} catch(Exception e) {
e.printStackTrace();
resultMap.put("result", "fail");
resultMap.put("msg", "저장 중 오류가 발생했습니다.");
}
return resultMap;
}
}

View File

@@ -4511,9 +4511,9 @@
COALESCE(NULLIF(PM.QUANTITY, '')::numeric, NULLIF(CI.ORDER_QUANTITY, '')::numeric, 0) AS QUANTITY,
COALESCE(NULLIF(PP.EXTRA_PROD_QTY, '')::numeric, 0) AS EXTRA_PROD_QTY,
COALESCE(NULLIF(PM.QUANTITY, '')::numeric, NULLIF(CI.ORDER_QUANTITY, '')::numeric, 0) + COALESCE(NULLIF(PP.EXTRA_PROD_QTY, '')::numeric, 0) AS TOTAL_PROD_QTY,
0 AS ASSEMBLY_QTY,
0 AS INSPECTION_QTY,
0 AS SHIP_WAIT_QTY,
COALESCE((SELECT SUM(RESULT_QTY) FROM PRODUCTION_RESULT PR WHERE PR.PROJECT_OBJID = PM.OBJID::VARCHAR AND PR.RESULT_TYPE = 'ASSEMBLY' AND PR.STATUS = 'active'), 0) AS ASSEMBLY_QTY,
COALESCE((SELECT SUM(RESULT_QTY) FROM PRODUCTION_RESULT PR WHERE PR.PROJECT_OBJID = PM.OBJID::VARCHAR AND PR.RESULT_TYPE = 'INSPECTION' AND PR.STATUS = 'active'), 0) AS INSPECTION_QTY,
COALESCE((SELECT SUM(RESULT_QTY) FROM PRODUCTION_RESULT PR WHERE PR.PROJECT_OBJID = PM.OBJID::VARCHAR AND PR.RESULT_TYPE = 'SHIP_WAIT' AND PR.STATUS = 'active'), 0) AS SHIP_WAIT_QTY,
'' AS EQUIPMENT_WBS,
PP.OBJID AS PROD_PLAN_OBJID,
PM.REGDATE AS SORT_DATE
@@ -4561,9 +4561,9 @@
COALESCE(NULLIF(PP.ORDER_QTY, '')::numeric, 0) AS QUANTITY,
COALESCE(NULLIF(PP.EXTRA_PROD_QTY, '')::numeric, 0) AS EXTRA_PROD_QTY,
COALESCE(NULLIF(PP.TOTAL_PROD_QTY, '')::numeric, 0) AS TOTAL_PROD_QTY,
0 AS ASSEMBLY_QTY,
0 AS INSPECTION_QTY,
0 AS SHIP_WAIT_QTY,
COALESCE((SELECT SUM(RESULT_QTY) FROM PRODUCTION_RESULT PR WHERE PR.PROJECT_OBJID = PP.OBJID::VARCHAR AND PR.RESULT_TYPE = 'ASSEMBLY' AND PR.STATUS = 'active'), 0) AS ASSEMBLY_QTY,
COALESCE((SELECT SUM(RESULT_QTY) FROM PRODUCTION_RESULT PR WHERE PR.PROJECT_OBJID = PP.OBJID::VARCHAR AND PR.RESULT_TYPE = 'INSPECTION' AND PR.STATUS = 'active'), 0) AS INSPECTION_QTY,
COALESCE((SELECT SUM(RESULT_QTY) FROM PRODUCTION_RESULT PR WHERE PR.PROJECT_OBJID = PP.OBJID::VARCHAR AND PR.RESULT_TYPE = 'SHIP_WAIT' AND PR.STATUS = 'active'), 0) AS SHIP_WAIT_QTY,
'' AS EQUIPMENT_WBS,
PP.OBJID AS PROD_PLAN_OBJID,
PP.REGDATE AS SORT_DATE
@@ -4621,31 +4621,54 @@
ORDER BY T.SORT_DATE DESC, T.PROJECT_NO DESC
</select>
<!-- 프로젝트 정보 조회 (생산계획 폼용) -->
<!-- 프로젝트 정보 조회 (생산계획 폼용) - PROJECT_MGMT 또는 PRODUCTION_PLAN에서 조회 -->
<select id="getProdPlanProjectInfo" parameterType="map" resultType="map">
SELECT
PM.OBJID,
PM.PROJECT_NO,
COALESCE(CI.PART_NO, PM.PART_NO) AS PART_NO,
COALESCE(CI.PART_NAME, PM.PART_NAME) AS PART_NAME,
COALESCE(CM.PRODUCT, PM.PRODUCT) AS PRODUCT_CODE,
COALESCE(CM.CATEGORY_CD, '') AS CATEGORY_CODE,
COALESCE(CM.CUSTOMER_OBJID, PM.CUSTOMER_OBJID) AS CUSTOMER_OBJID,
COALESCE(CI.DUE_DATE, PM.DUE_DATE, CM.REQ_DEL_DATE) AS REQ_DEL_DATE,
PM.QUANTITY AS ORDER_QTY,
CM.CUSTOMER_REQUEST,
(
SELECT STRING_AGG(CIS.SERIAL_NO, ', ' ORDER BY CIS.SERIAL_NO)
FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID = CI.OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
) AS SERIAL_NO
FROM PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT JOIN CONTRACT_ITEM CI ON CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'
WHERE PM.OBJID = #{projectObjid}
SELECT * FROM (
-- 1. PROJECT_MGMT 기반 조회
SELECT
PM.OBJID::VARCHAR AS OBJID,
COALESCE(PM.PROJECT_NO, '') AS PROJECT_NO,
COALESCE(CI.PART_NO, PM.PART_NO, '') AS PART_NO,
COALESCE(CI.PART_NAME, PM.PART_NAME, '') AS PART_NAME,
COALESCE(CM.PRODUCT, PM.PRODUCT, '') AS PRODUCT_CODE,
COALESCE(CM.CATEGORY_CD, '') AS CATEGORY_CODE,
COALESCE(CM.CUSTOMER_OBJID, PM.CUSTOMER_OBJID, '')::VARCHAR AS CUSTOMER_OBJID,
COALESCE(CI.DUE_DATE, PM.DUE_DATE, CM.REQ_DEL_DATE, '') AS REQ_DEL_DATE,
COALESCE(NULLIF(PM.QUANTITY, '')::numeric, 0) AS ORDER_QTY,
COALESCE((SELECT NULLIF(PP.EXTRA_PROD_QTY, '')::numeric FROM PRODUCTION_PLAN PP WHERE PP.PROJECT_OBJID = PM.OBJID AND UPPER(PP.STATUS) = 'ACTIVE' LIMIT 1), 0) AS EXTRA_PROD_QTY,
COALESCE(CM.CUSTOMER_REQUEST, '') AS CUSTOMER_REQUEST,
COALESCE((
SELECT STRING_AGG(CIS.SERIAL_NO, ', ' ORDER BY CIS.SERIAL_NO)
FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID = CI.OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
), '') AS SERIAL_NO
FROM PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT JOIN CONTRACT_ITEM CI ON CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'
WHERE PM.OBJID::VARCHAR = #{projectObjid}
UNION ALL
-- 2. PRODUCTION_PLAN 기반 조회 (OBJID로 직접 조회)
SELECT
PP.OBJID::VARCHAR AS OBJID,
'' AS PROJECT_NO,
COALESCE(PP.PART_NO, '') AS PART_NO,
COALESCE(PP.PART_NAME, '') AS PART_NAME,
COALESCE(PP.PRODUCT_CODE, '') AS PRODUCT_CODE,
COALESCE(PP.CATEGORY_CODE, '') AS CATEGORY_CODE,
COALESCE(PP.CUSTOMER_OBJID, '')::VARCHAR AS CUSTOMER_OBJID,
COALESCE(PP.REQ_DEL_DATE, '') AS REQ_DEL_DATE,
COALESCE(NULLIF(PP.ORDER_QTY, '')::numeric, 0) AS ORDER_QTY,
COALESCE(NULLIF(PP.EXTRA_PROD_QTY, '')::numeric, 0) AS EXTRA_PROD_QTY,
COALESCE(PP.CUSTOMER_REQUEST, '') AS CUSTOMER_REQUEST,
COALESCE(PP.SERIAL_NO, '') AS SERIAL_NO
FROM PRODUCTION_PLAN PP
WHERE PP.OBJID::VARCHAR = #{projectObjid}
) T
LIMIT 1
</select>
@@ -4765,6 +4788,7 @@
RESULT_TYPE,
RESULT_DATE,
RESULT_QTY,
ROW_SEQ,
SERIAL_NO,
WORKER_ID,
WORKER_NAME,
@@ -4778,6 +4802,7 @@
#{RESULT_TYPE},
#{RESULT_DATE},
#{RESULT_QTY},
#{ROW_SEQ},
#{SERIAL_NO},
#{userId},
#{WORKER_NAME},
@@ -4871,4 +4896,40 @@
ORDER BY MD.RAW_MATERIAL_PART_NO
</select>
<!-- 생산실적 날짜별 조회 (피봇) -->
<select id="getProdResultListByDate" parameterType="map" resultType="com.pms.common.UpperKeyMap">
SELECT
ROW_SEQ,
RESULT_DATE,
COALESCE(SUM(CASE WHEN RESULT_TYPE = 'ASSEMBLY' THEN RESULT_QTY ELSE 0 END), 0) AS ASSEMBLY_QTY,
COALESCE(SUM(CASE WHEN RESULT_TYPE = 'INSPECTION' THEN RESULT_QTY ELSE 0 END), 0) AS INSPECTION_QTY,
COALESCE(SUM(CASE WHEN RESULT_TYPE = 'SHIP_WAIT' THEN RESULT_QTY ELSE 0 END), 0) AS SHIP_WAIT_QTY,
MAX(REMARK) AS REMARK
FROM PRODUCTION_RESULT
WHERE PROJECT_OBJID = #{projectObjid}
AND STATUS = 'active'
GROUP BY ROW_SEQ, RESULT_DATE
ORDER BY ROW_SEQ ASC
</select>
<!-- 생산실적 행별 삭제 -->
<delete id="deleteProdResultByRowSeq" parameterType="map">
DELETE FROM PRODUCTION_RESULT
WHERE PROJECT_OBJID = #{projectObjid}
AND ROW_SEQ = #{rowSeq}
</delete>
<!-- 생산실적 날짜별 삭제 (기존 데이터 삭제 후 재입력용) -->
<delete id="deleteProdResultByDate" parameterType="map">
DELETE FROM PRODUCTION_RESULT
WHERE PROJECT_OBJID = #{projectObjid}
AND RESULT_DATE = #{resultDate}
</delete>
<!-- 생산실적 프로젝트 전체 삭제 -->
<delete id="deleteProdResultByProject" parameterType="map">
DELETE FROM PRODUCTION_RESULT
WHERE PROJECT_OBJID = #{projectObjid}
</delete>
</mapper>

View File

@@ -2125,4 +2125,118 @@ public class ProductionPlanningService {
return resultList;
}
/**
* 생산실적 날짜별 조회
*/
public List getProdResultListByDate(Map<String, Object> paramMap) {
List resultList = new ArrayList();
SqlSession sqlSession = null;
try {
sqlSession = SqlMapConfig.getInstance().getSqlSession();
resultList = sqlSession.selectList("productionplanning.getProdResultListByDate", paramMap);
} catch(Exception e) {
e.printStackTrace();
} finally {
if(sqlSession != null) {
sqlSession.close();
}
}
return resultList;
}
/**
* 생산실적 날짜별 저장
* - 기존 데이터 전체 삭제 후 새로 입력
*/
@SuppressWarnings("unchecked")
public boolean saveProdResultByDate(Map<String, Object> paramMap) {
boolean result = false;
SqlSession sqlSession = null;
try {
sqlSession = SqlMapConfig.getInstance().getSqlSession();
String projectObjid = CommonUtils.nullToEmpty((String)paramMap.get("projectObjid"));
String userId = CommonUtils.nullToEmpty((String)paramMap.get("userId"));
String userName = CommonUtils.nullToEmpty((String)paramMap.get("userName"));
List<Map<String, Object>> resultList = (List<Map<String, Object>>)paramMap.get("resultList");
// 기존 데이터 전체 삭제
Map<String, Object> deleteParam = new HashMap<String, Object>();
deleteParam.put("projectObjid", projectObjid);
sqlSession.delete("productionplanning.deleteProdResultByProject", deleteParam);
// 새로 입력 (행별로 ROW_SEQ 부여)
if(resultList != null && resultList.size() > 0) {
int rowSeq = 1; // 행 순번
for(Map<String, Object> row : resultList) {
String resultDate = CommonUtils.nullToEmpty((String)row.get("RESULT_DATE"));
if("".equals(resultDate)) continue;
int assemblyQty = getIntValue(row.get("ASSEMBLY_QTY"));
int inspectionQty = getIntValue(row.get("INSPECTION_QTY"));
int shipWaitQty = getIntValue(row.get("SHIP_WAIT_QTY"));
String remark = CommonUtils.nullToEmpty((String)row.get("REMARK"));
// 완조립 수량 입력 (0이어도 입력)
Map<String, Object> insertParam = new HashMap<String, Object>();
insertParam.put("OBJID", CommonUtils.createObjId());
insertParam.put("PROJECT_OBJID", projectObjid);
insertParam.put("RESULT_TYPE", "ASSEMBLY");
insertParam.put("RESULT_DATE", resultDate);
insertParam.put("RESULT_QTY", assemblyQty);
insertParam.put("ROW_SEQ", rowSeq);
insertParam.put("WORKER_NAME", userName);
insertParam.put("REMARK", remark);
insertParam.put("userId", userId);
sqlSession.insert("productionplanning.insertProdResult", insertParam);
// 검사 수량 입력 (0이어도 입력)
insertParam = new HashMap<String, Object>();
insertParam.put("OBJID", CommonUtils.createObjId());
insertParam.put("PROJECT_OBJID", projectObjid);
insertParam.put("RESULT_TYPE", "INSPECTION");
insertParam.put("RESULT_DATE", resultDate);
insertParam.put("RESULT_QTY", inspectionQty);
insertParam.put("ROW_SEQ", rowSeq);
insertParam.put("WORKER_NAME", userName);
insertParam.put("REMARK", remark);
insertParam.put("userId", userId);
sqlSession.insert("productionplanning.insertProdResult", insertParam);
// 출하대기 수량 입력 (0이어도 입력)
insertParam = new HashMap<String, Object>();
insertParam.put("OBJID", CommonUtils.createObjId());
insertParam.put("PROJECT_OBJID", projectObjid);
insertParam.put("RESULT_TYPE", "SHIP_WAIT");
insertParam.put("RESULT_DATE", resultDate);
insertParam.put("RESULT_QTY", shipWaitQty);
insertParam.put("ROW_SEQ", rowSeq);
insertParam.put("WORKER_NAME", userName);
insertParam.put("REMARK", remark);
insertParam.put("userId", userId);
sqlSession.insert("productionplanning.insertProdResult", insertParam);
rowSeq++; // 다음 행
}
}
sqlSession.commit();
result = true;
} catch(Exception e) {
e.printStackTrace();
if(sqlSession != null) {
sqlSession.rollback();
}
} finally {
if(sqlSession != null) {
sqlSession.close();
}
}
return result;
}
}