프로젝트 생성시 contract_item.objid 도 포함하도록 수정

This commit is contained in:
2026-03-24 16:32:44 +09:00
parent d80a3f5341
commit a756123105
4 changed files with 139 additions and 28 deletions

View File

@@ -245,6 +245,7 @@
}
var item = {
objId: $row.find(".item-objid").val() || '',
partObjId: $row.find(".item-part-objid").val(),
partNo: $row.find(".item-part-no").val() ? $row.find(".item-part-no").val().trim() : "",
partName: $row.find(".item-part-name").val() ? $row.find(".item-part-name").val().trim() : "",

View File

@@ -3031,10 +3031,12 @@
FROM
PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID
AND PM.PART_OBJID = CI.PART_OBJID
-- CONTRACT_ITEM과 LEFT JOIN하여 품목별로 펼쳐서 보이기
-- LEFT JOIN CONTRACT_ITEM CI ON CM.OBJID::VARCHAR = CI.CONTRACT_OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON (
CASE
WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID
END
)
AND CI.STATUS = 'ACTIVE'
WHERE 1=1
AND PM.PROJECT_NO IS NOT NULL
@@ -4597,8 +4599,12 @@
FROM
PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID
AND PM.PART_OBJID = CI.PART_OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON (
CASE
WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID
END
)
AND CI.STATUS = 'ACTIVE'
LEFT OUTER JOIN PRODUCTION_PLAN PP ON PP.PROJECT_OBJID = PM.OBJID
AND PP.STATUS = 'active'
@@ -4731,8 +4737,13 @@
COALESCE(CI.PART_NAME, PM.PART_NAME, '') AS PART_NAME
FROM PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID
AND PM.PART_OBJID = CI.PART_OBJID AND CI.STATUS = 'ACTIVE'
LEFT OUTER JOIN CONTRACT_ITEM CI ON (
CASE
WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID
END
)
AND CI.STATUS = 'ACTIVE'
WHERE PM.OBJID::VARCHAR = #{projectObjid}::VARCHAR
</select>
@@ -4935,7 +4946,13 @@
FROM
PROJECT_MGMT PM
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON (
CASE
WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID
END
)
AND CI.STATUS = 'ACTIVE'
AND PM.PART_OBJID = CI.PART_OBJID
AND CI.STATUS = 'ACTIVE'
LEFT OUTER JOIN PRODUCTION_PLAN PP ON PP.PROJECT_OBJID = PM.OBJID
@@ -5008,8 +5025,12 @@
), '') 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
LEFT JOIN CONTRACT_ITEM CI ON (
CASE
WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID
END
)
AND CI.STATUS = 'ACTIVE'
WHERE PM.OBJID::VARCHAR = #{projectObjid}
@@ -5051,8 +5072,12 @@
COALESCE(
(SELECT STRING_AGG(CIS.SERIAL_NO, ', ' ORDER BY CIS.SERIAL_NO)
FROM PROJECT_MGMT PM
JOIN CONTRACT_ITEM CI ON CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID AND CI.STATUS = 'ACTIVE'
JOIN CONTRACT_ITEM CI ON (
CASE
WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID
END
) AND CI.STATUS = 'ACTIVE'
JOIN CONTRACT_ITEM_SERIAL CIS ON CIS.ITEM_OBJID = CI.OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE' AND CIS.SERIAL_NO IS NOT NULL
WHERE PM.OBJID::VARCHAR = PP.PROJECT_OBJID),
@@ -5346,7 +5371,13 @@
FROM MBOM_HISTORY MH
INNER JOIN MBOM_HEADER MHD ON MH.MBOM_HEADER_OBJID = MHD.OBJID
INNER JOIN PROJECT_MGMT PM ON MHD.PROJECT_OBJID = PM.OBJID::VARCHAR
LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID
LEFT OUTER JOIN CONTRACT_ITEM CI ON (
CASE
WHEN PM.CONTRACT_ITEM_OBJID IS NOT NULL THEN CI.OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
ELSE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID AND CI.PART_OBJID = PM.PART_OBJID
END
)
AND CI.STATUS = 'ACTIVE'
LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID
WHERE 1=1
<if test="search_category_cd != null and search_category_cd != ''">
@@ -5394,5 +5425,60 @@
INNER JOIN PROJECT_MGMT PM ON MHD.PROJECT_OBJID = PM.OBJID::VARCHAR
WHERE MH.OBJID::VARCHAR = #{historyObjId}
</select>
<!-- M-BOM → ERP BOM 동기화용: 모품목-자품목 관계 추출 -->
<select id="selectMbomBomRelationsForErp" parameterType="map" resultType="map">
SELECT
ITEM_PARENT_CD,
ITEM_CHILD_CD,
JUST_QT,
SUPPLY_TYPE,
ROW_NUMBER() OVER (PARTITION BY ITEM_PARENT_CD ORDER BY SEQ, CHILD_OBJID) AS BOM_SQ
FROM (
SELECT
CASE
WHEN MD.PARENT_OBJID IS NULL OR MD.PARENT_OBJID = ''
THEN MH.PART_NO
ELSE PARENT_MD.PART_NO
END AS ITEM_PARENT_CD,
MD.PART_NO AS ITEM_CHILD_CD,
COALESCE(MD.QTY, 1) AS JUST_QT,
COALESCE(MD.SUPPLY_TYPE, '') AS SUPPLY_TYPE,
MD.SEQ,
MD.CHILD_OBJID
FROM MBOM_DETAIL MD
JOIN MBOM_HEADER MH ON MH.OBJID::VARCHAR = MD.MBOM_HEADER_OBJID::VARCHAR
LEFT JOIN MBOM_DETAIL PARENT_MD
ON MD.PARENT_OBJID = PARENT_MD.CHILD_OBJID
AND MD.MBOM_HEADER_OBJID = PARENT_MD.MBOM_HEADER_OBJID
AND PARENT_MD.STATUS = 'ACTIVE'
WHERE MD.MBOM_HEADER_OBJID = #{mbomHeaderObjid}
AND MD.STATUS = 'ACTIVE'
) SUB
ORDER BY ITEM_PARENT_CD, BOM_SQ
</select>
<!-- M-BOM → ERP BOM 동기화용: DISTINCT 모품목 목록 -->
<select id="selectDistinctParentItemsForErp" parameterType="map" resultType="string">
SELECT DISTINCT ITEM_PARENT_CD
FROM (
SELECT
CASE
WHEN MD.PARENT_OBJID IS NULL OR MD.PARENT_OBJID = ''
THEN MH.PART_NO
ELSE PARENT_MD.PART_NO
END AS ITEM_PARENT_CD
FROM MBOM_DETAIL MD
JOIN MBOM_HEADER MH ON MH.OBJID::VARCHAR = MD.MBOM_HEADER_OBJID::VARCHAR
LEFT JOIN MBOM_DETAIL PARENT_MD
ON MD.PARENT_OBJID = PARENT_MD.CHILD_OBJID
AND MD.MBOM_HEADER_OBJID = PARENT_MD.MBOM_HEADER_OBJID
AND PARENT_MD.STATUS = 'ACTIVE'
WHERE MD.MBOM_HEADER_OBJID = #{mbomHeaderObjid}
AND MD.STATUS = 'ACTIVE'
) SUB
WHERE ITEM_PARENT_CD IS NOT NULL AND ITEM_PARENT_CD != ''
</select>
</mapper>

View File

@@ -7470,6 +7470,7 @@ SELECT
,PART_NO
,PART_NAME
,QUANTITY
,CONTRACT_ITEM_OBJID
)
(
@@ -7611,12 +7612,21 @@ SELECT
,#{part_no}
,#{part_name}
,#{quantity}
,#{contract_item_objid}
FROM CONTRACT_MGMT
WHERE OBJID=#{objId}
)
</insert>
<!-- 기존 프로젝트에 CONTRACT_ITEM_OBJID 매핑 업데이트 -->
<update id="updateProjectContractItemObjid" parameterType="map">
UPDATE PROJECT_MGMT
SET CONTRACT_ITEM_OBJID = #{contract_item_objid}
WHERE CONTRACT_OBJID = #{contract_objid}
AND PART_OBJID = #{part_objid}
AND CONTRACT_ITEM_OBJID IS NULL
</update>
<!-- //계약정보를 받아 프로젝트 TASK 최초저장 -->
<insert id="insertProjectTask" parameterType="map">
INSERT INTO

View File

@@ -2699,21 +2699,19 @@ private String encodeImageToBase64(String imagePath) {
JSONParser parser = new JSONParser();
JSONArray jsonArray = (JSONArray) parser.parse(itemsJson);
// 기존 품목 삭제 (전체 삭제 후 재등록 방식)
Map<String, Object> deleteParam = new HashMap<String, Object>();
deleteParam.put("contractObjId", contract_objid);
deleteParam.put("userId", person.getUserId());
sqlSession.update("contractMgmt.deleteContractItems", deleteParam);
// UPSERT 방식으로 품목 저장 (OBJID 유지 - CONTRACT_ITEM_OBJID 매핑 보존)
Set<String> currentItemObjIds = new HashSet<String>();
for(int i = 0; i < jsonArray.size(); i++) {
JSONObject item = (JSONObject) jsonArray.get(i);
Map<String, Object> itemMap = new HashMap<String, Object>();
// 품목 기본 정보
// 품목 기본 정보 - 기존 OBJID가 있으면 유지
String itemObjId = item.get("objId") != null ? item.get("objId").toString() : "";
if("".equals(itemObjId) || itemObjId.startsWith("temp_")) {
itemObjId = CommonUtils.createObjId();
}
currentItemObjIds.add(itemObjId);
itemMap.put("objId", itemObjId);
itemMap.put("contractObjId", contract_objid);
@@ -2741,8 +2739,13 @@ private String encodeImageToBase64(String imagePath) {
itemMap.put("orderTotalAmount", orderTotalAmount);
itemMap.put("writer", person.getUserId());
// 품목 저장 (통합 등록용 - 수주 정보 포함)
sqlSession.insert("contractMgmt.insertContractItemWithOrder", itemMap);
// 품목 UPSERT (기존 OBJID면 UPDATE, 새 OBJID면 INSERT)
sqlSession.insert("contractMgmt.upsertContractItemWithOrder", itemMap);
// 기존 S/N 삭제 후 재등록
Map<String, Object> deleteSnParam = new HashMap<String, Object>();
deleteSnParam.put("itemObjId", itemObjId);
sqlSession.delete("contractMgmt.deleteItemSerials", deleteSnParam);
// S/N 저장 (별도 테이블)
JSONArray snArray = (JSONArray) item.get("snList");
@@ -2758,7 +2761,6 @@ private String encodeImageToBase64(String imagePath) {
sqlSession.insert("contractMgmt.insertContractItemSerial", snMap);
}
}
// 합계 계산 (소수점 지원)
try {
totalSupplyPrice += Double.parseDouble(orderSupplyPrice);
@@ -2768,12 +2770,21 @@ private String encodeImageToBase64(String imagePath) {
System.out.println("합계 계산 실패 - supply:" + orderSupplyPrice + ", vat:" + orderVat + ", total:" + orderTotalAmount);
}
}
// 프론트에서 전달되지 않은 품목들은 INACTIVE 처리 (삭제된 품목)
if(!currentItemObjIds.isEmpty()) {
Map<String, Object> inactiveParam = new HashMap<String, Object>();
inactiveParam.put("contractObjId", contract_objid);
inactiveParam.put("currentItemObjIds", new ArrayList<String>(currentItemObjIds));
inactiveParam.put("userId", person.getUserId());
sqlSession.update("contractMgmt.inactivateRemovedItems", inactiveParam);
}
} catch (Exception e) {
e.printStackTrace();
throw new Exception("품목 정보 저장 중 오류가 발생했습니다.");
}
}
// 3. 수주 합계 업데이트
paramMap.put("order_supply_price", String.valueOf(totalSupplyPrice));
paramMap.put("order_vat", String.valueOf(totalVat));
@@ -2835,6 +2846,7 @@ private String encodeImageToBase64(String imagePath) {
projectParam.put("OBJID", CommonUtils.createObjId());
projectParam.put("is_temp", '1');
projectParam.put("part_objid", item.get("PART_OBJID"));
projectParam.put("contract_item_objid", String.valueOf(item.get("OBJID")));
projectParam.put("part_no", item.get("PART_NO"));
projectParam.put("part_name", item.get("PART_NAME"));
// Machine인 경우 각 프로젝트의 수량은 1, 아니면 원래 수량
@@ -3068,6 +3080,8 @@ private String encodeImageToBase64(String imagePath) {
// 품목별 정보 설정
projectParam.put("OBJID", CommonUtils.createObjId());
projectParam.put("is_temp", '1');
projectParam.put("contract_item_objid", String.valueOf(item.get("OBJID")));
System.out.println("CONTRACT_ITEM_OBJID 매핑: " + item.get("OBJID") + " (type: " + (item.get("OBJID") != null ? item.get("OBJID").getClass().getName() : "null") + ")");
projectParam.put("part_objid", item.get("PART_OBJID"));
projectParam.put("part_no", item.get("PART_NO"));
projectParam.put("part_name", item.get("PART_NAME"));