Merge remote-tracking branch 'origin/ycplm_node' into V20260210

This commit is contained in:
2026-03-26 15:41:44 +09:00
11 changed files with 1097 additions and 68 deletions

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

@@ -3933,12 +3933,13 @@
AND S.SERIAL_NO IS NOT NULL) AS SERIAL_NO
-- 요청납기: CONTRACT_ITEM 우선, 없으면 PROJECT_MGMT.DUE_DATE, 없으면 CONTRACT_MGMT.due_date
,COALESCE(
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'),
T.DUE_DATE,
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
ORDER BY CI.OBJID DESC LIMIT 1),
T.DUE_DATE,
(SELECT CM.due_date FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID)
) AS REQ_DEL_DATE
-- 영업관리_주문서관리_수주등록
@@ -3951,9 +3952,10 @@
,PRODUCTION_TEAM_3
-- 출하일: sales_registration 테이블에서 가져오기 (영업관리_판매관리와 동일)
,COALESCE(
(SELECT TO_CHAR(SR.shipping_date, 'YYYY-MM-DD')
FROM sales_registration SR
WHERE SR.project_no = T.PROJECT_NO),
(SELECT TO_CHAR(SR.shipping_date, 'YYYY-MM-DD')
FROM sales_registration SR
WHERE SR.project_no = T.PROJECT_NO
ORDER BY SR.sale_no DESC LIMIT 1),
''
) AS SHIPMENT_DATE
,(((SELECT SUM(COALESCE(DESIGN_RATE,'0')::INTEGER) / COUNT(1) FROM PMS_WBS_TASK AS O WHERE O.CONTRACT_OBJID = T.OBJID)
@@ -7468,6 +7470,7 @@ SELECT
,PART_NO
,PART_NAME
,QUANTITY
,CONTRACT_ITEM_OBJID
)
(
@@ -7609,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

@@ -1560,10 +1560,12 @@
,CONTRACT_DEL_DATE = #{contract_del_date}
,CONTRACT_COMPANY = #{contract_company}
,CONTRACT_DATE = #{contract_date}
,PO_NO = #{po_no}
,MANUFACTURE_PLANT = #{manufacture_plant}
,CONTRACT_RESULT = #{contract_result}
,PROJECT_NAME = #{project_name}
,PO_NO = #{po_no}
,MANUFACTURE_PLANT = #{manufacture_plant}
<if test="contract_result != null and contract_result != ''">
,CONTRACT_RESULT = #{contract_result}
</if>
,PROJECT_NAME = #{project_name}
,SPEC_USER_ID = #{spec_user_id}
,SPEC_PLAN_DATE = #{spec_plan_date}
,SPEC_COMP_DATE = #{spec_comp_date}
@@ -1730,10 +1732,12 @@
,CONTRACT_DEL_DATE = #{contract_del_date}
,CONTRACT_COMPANY = #{contract_company}
,CONTRACT_DATE = #{contract_date}
,PO_NO = #{po_no}
,MANUFACTURE_PLANT = #{manufacture_plant}
,CONTRACT_RESULT = #{contract_result}
,PROJECT_NAME = #{project_name}
,PO_NO = #{po_no}
,MANUFACTURE_PLANT = #{manufacture_plant}
<if test="contract_result != null and contract_result != ''">
,CONTRACT_RESULT = #{contract_result}
</if>
,PROJECT_NAME = #{project_name}
,AREA_CD = #{area_cd} -->
</update>
@@ -4991,7 +4995,9 @@ WHERE
<update id="updateOrderInfo" parameterType="map">
UPDATE CONTRACT_MGMT
SET
<if test="contract_result != null and contract_result != ''">
CONTRACT_RESULT = #{contract_result},
</if>
PO_NO = #{po_no},
ORDER_DATE = #{order_date},
CONTRACT_CURRENCY = #{contract_currency},
@@ -5083,7 +5089,9 @@ WHERE
PAID_TYPE = #{paid_type},
RECEIPT_DATE = #{receipt_date},
REQ_DEL_DATE = #{req_del_date},
<if test="contract_result != null and contract_result != ''">
CONTRACT_RESULT = #{contract_result},
</if>
PO_NO = #{po_no},
ORDER_DATE = #{order_date},
CONTRACT_CURRENCY = #{contract_currency},
@@ -5629,6 +5637,67 @@ WHERE
STATUS = 'ACTIVE'
</insert>
<!-- 품목 UPSERT (수주 정보 포함 - 통합등록용) -->
<insert id="upsertContractItemWithOrder" parameterType="map">
INSERT INTO CONTRACT_ITEM (
OBJID,
CONTRACT_OBJID,
SEQ,
PART_OBJID,
PART_NO,
PART_NAME,
QUANTITY,
DUE_DATE,
CUSTOMER_REQUEST,
RETURN_REASON,
REGDATE,
WRITER,
STATUS,
ORDER_QUANTITY,
ORDER_UNIT_PRICE,
ORDER_SUPPLY_PRICE,
ORDER_VAT,
ORDER_TOTAL_AMOUNT
) VALUES (
#{objId},
#{contractObjId},
#{seq},
#{partObjId},
#{partNo},
#{partName},
CASE WHEN #{quantity} = '' OR #{quantity} IS NULL THEN NULL ELSE #{quantity}::INTEGER END,
#{dueDate},
#{customerRequest},
#{returnReason},
NOW(),
#{writer},
'ACTIVE',
#{orderQuantity},
#{orderUnitPrice},
#{orderSupplyPrice},
#{orderVat},
#{orderTotalAmount}
)
ON CONFLICT (OBJID) DO UPDATE
SET
SEQ = #{seq},
PART_OBJID = #{partObjId},
PART_NO = #{partNo},
PART_NAME = #{partName},
QUANTITY = CASE WHEN #{quantity} = '' OR #{quantity} IS NULL THEN NULL ELSE #{quantity}::INTEGER END,
DUE_DATE = #{dueDate},
CUSTOMER_REQUEST = #{customerRequest},
RETURN_REASON = #{returnReason},
CHGDATE = NOW(),
CHG_USER_ID = #{writer},
STATUS = 'ACTIVE',
ORDER_QUANTITY = #{orderQuantity},
ORDER_UNIT_PRICE = #{orderUnitPrice},
ORDER_SUPPLY_PRICE = #{orderSupplyPrice},
ORDER_VAT = #{orderVat},
ORDER_TOTAL_AMOUNT = #{orderTotalAmount}
</insert>
<!-- S/N UPSERT (INSERT or UPDATE) -->
<insert id="upsertContractItemSerial" parameterType="map">
INSERT INTO CONTRACT_ITEM_SERIAL (

View File

@@ -844,14 +844,9 @@
FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID) AS PAYMENT_TYPE,
T.PART_NO AS PRODUCT_NO,
T.PART_NAME AS PRODUCT_NAME,
-- S/N: CONTRACT_ITEM_SERIAL(마스터) 우선, 없으면 판매등록 텍스트 fallback (그리드 요약용)
-- S/N: CONTRACT_ITEM_SERIAL(마스터) 우선, 없으면 판매등록 텍스트 fallback (콤마 구분 전체 목록)
COALESCE(
(SELECT
CASE
WHEN COUNT(*) = 0 THEN NULL
WHEN COUNT(*) = 1 THEN MIN(CIS.SERIAL_NO)
ELSE MIN(CIS.SERIAL_NO) || ' 외 ' || (COUNT(*) - 1)::TEXT || '건'
END
(SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
FROM CONTRACT_ITEM CI
LEFT JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND UPPER(CIS.STATUS) = 'ACTIVE'
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
@@ -860,23 +855,34 @@
AND CIS.SERIAL_NO IS NOT NULL),
SR.serial_no
) AS SERIAL_NO,
-- 분할S/N: shipment_log에서 해당 프로젝트의 모든 분할S/N 집계
COALESCE(
(SELECT STRING_AGG(SL_SN.split_serial_no, ',' ORDER BY SL_SN.log_id)
FROM shipment_log SL_SN
WHERE SL_SN.target_objid = T.PROJECT_NO
AND SL_SN.split_serial_no IS NOT NULL
AND SL_SN.split_serial_no != ''),
''
) AS SPLIT_SERIAL_NO,
COALESCE(NULLIF(REPLACE(T.QUANTITY, ',', ''), '')::numeric, 0) AS ORDER_QUANTITY,
-- 요청납기: CONTRACT_ITEM 우선, 없으면 PROJECT_MGMT, 없으면 CONTRACT_MGMT
COALESCE(
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'),
T.DUE_DATE,
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
ORDER BY CI.OBJID DESC LIMIT 1),
T.DUE_DATE,
(SELECT CM.due_date FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID)
) AS REQUEST_DATE,
-- 고객요청사항: CONTRACT_ITEM에서만 가져옴 (견적관리와 완전히 동일)
(SELECT CI.CUSTOMER_REQUEST
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE') AS CUSTOMER_REQUEST,
(SELECT CI.CUSTOMER_REQUEST
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
ORDER BY CI.OBJID DESC LIMIT 1) AS CUSTOMER_REQUEST,
CODE_NAME(T.CONTRACT_RESULT) AS ORDER_STATUS,
(SELECT CM.PO_NO FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID) AS PO_NO,
COALESCE(T.CONTRACT_DATE, (SELECT CM.order_date FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID)) AS ORDER_DATE,
@@ -1572,20 +1578,22 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
COALESCE(NULLIF(REPLACE(T.QUANTITY, ',', ''), '')::numeric, 0) AS ORDER_QUANTITY,
-- 요청납기: CONTRACT_ITEM 우선, 없으면 PROJECT_MGMT, 없으면 CONTRACT_MGMT
COALESCE(
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'),
T.DUE_DATE,
(SELECT CI.DUE_DATE
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
ORDER BY CI.OBJID DESC LIMIT 1),
T.DUE_DATE,
(SELECT CM.due_date FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID)
) AS REQUEST_DATE,
-- 고객요청사항: CONTRACT_ITEM에서만 가져옴 (견적관리와 완전히 동일)
(SELECT CI.CUSTOMER_REQUEST
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE') AS CUSTOMER_REQUEST,
(SELECT CI.CUSTOMER_REQUEST
FROM CONTRACT_ITEM CI
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
ORDER BY CI.OBJID DESC LIMIT 1) AS CUSTOMER_REQUEST,
CODE_NAME(T.CONTRACT_RESULT) AS ORDER_STATUS,
T.PO_NO,
COALESCE(T.CONTRACT_DATE, (SELECT CM.order_date FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID)) AS ORDER_DATE,
@@ -1898,7 +1906,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
remaining_quantity, shipping_status, shipping_date, shipping_method,
sales_unit_price, sales_supply_price, sales_vat, sales_total_amount,
sales_currency, sales_exchange_rate, manager_user_id, incoterms,
serial_no, parent_sale_no, reg_user_id
serial_no, parent_sale_no, reg_user_id, split_serial_no
) VALUES (
#{targetObjid}, 'SPLIT_SHIPMENT', '분할 출하',
#{salesQuantity}::integer, #{originalQuantity}::integer, #{remainingQuantity}::integer,
@@ -1912,7 +1920,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
#{shippingMethod}, #{salesUnitPrice}::numeric, #{salesSupplyPrice}::numeric,
#{salesVat}::numeric, #{salesTotalAmount}::numeric, #{salesCurrency},
#{salesExchangeRate}::numeric, #{managerUserId}, #{incoterms}, #{serialNo},
#{parentSaleNo}::integer, #{cretEmpNo}
#{parentSaleNo}::integer, #{cretEmpNo}, #{splitSerialNo}
)
</insert>
@@ -1990,6 +1998,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
WHERE PM.PROJECT_NO = SL.target_objid AND CI.STATUS = 'ACTIVE'
), '-') AS serial_no,
SL.target_objid AS project_no,
COALESCE(SL.split_serial_no, '-') AS split_serial_no,
TO_CHAR(SL.reg_date, 'YYYY-MM-DD HH24:MI:SS') AS reg_date
FROM shipment_log SL
WHERE SL.target_objid = #{projectNo}
@@ -2021,6 +2030,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
COALESCE(SL.sales_exchange_rate, 0) AS SALES_EXCHANGE_RATE,
COALESCE(SL.manager_user_id, '') AS MANAGER,
COALESCE(SL.incoterms, '') AS INCOTERMS,
COALESCE(SL.split_serial_no, '') AS SPLIT_SERIAL_NO,
COALESCE(SL.original_quantity, 0) AS ORDER_QUANTITY,
COALESCE(SL.remaining_quantity, 0) AS REMAINING_QUANTITY
FROM shipment_log SL
@@ -2066,6 +2076,9 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
<if test="incoterms != null and incoterms != ''">
, incoterms = #{incoterms}
</if>
<if test="splitSerialNo != null and splitSerialNo != ''">
, split_serial_no = #{splitSerialNo}
</if>
WHERE log_id = #{logId}::integer
</update>
@@ -2402,6 +2415,7 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID AND CI.STATUS = 'ACTIVE'
), '') AS SERIAL_NO,
COALESCE(SL.split_serial_no, '') AS SPLIT_SERIAL_NO,
COALESCE(NULLIF(REPLACE(T.QUANTITY, ',', ''), '')::numeric, 0) AS ORDER_QUANTITY,
(SELECT CM.PO_NO FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID) AS PO_NO,
COALESCE(T.CONTRACT_DATE, (SELECT CM.order_date FROM CONTRACT_MGMT CM WHERE CM.OBJID = T.CONTRACT_OBJID)) AS ORDER_DATE,
@@ -2738,6 +2752,22 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
WHERE PROJECT_NO = #{projectNo}
</update>
<!-- 프로젝트의 이미 사용된 분할S/N 목록 조회 -->
<select id="getUsedSplitSerialNos" parameterType="map" resultType="map">
/* salesNcollectMgmt.getUsedSplitSerialNos - 이미 사용된 분할S/N 조회 */
SELECT
SL.log_id,
COALESCE(SL.split_serial_no, '') AS split_serial_no
FROM shipment_log SL
WHERE SL.target_objid = #{projectNo}
<if test="excludeLogId != null and excludeLogId != ''">
AND SL.log_id != #{excludeLogId}::integer
</if>
AND SL.split_serial_no IS NOT NULL
AND SL.split_serial_no != ''
ORDER BY SL.log_id
</select>
</mapper>

View File

@@ -36,7 +36,65 @@
#serial_no:-ms-input-placeholder {
color: #999 !important;
}
/* ===== 팝업 폼 전체 너비 확장 ===== */
section.business_popup_min_width {
padding: 0 !important;
margin: 0 auto !important;
width: calc(100% - 16px) !important;
}
#EntirePopupFormWrap {
width: 100% !important;
margin: 5px 0 0 0 !important;
}
/* ===== 품목 그리드 컬럼 리사이즈 ===== */
#EntirePopupFormWrap > table {
width: 100% !important;
}
#itemListTable {
table-layout: fixed;
width: 100%;
}
#itemListTable th {
position: relative;
user-select: none;
}
#itemListTable th .col-resizer {
position: absolute;
right: -4.5px;
top: 0;
width: 7px;
height: 100%;
cursor: col-resize;
z-index: 10;
}
#itemListTable th .col-resizer:hover {
background: rgba(0, 120, 215, 0.3);
}
/* ===== Select2 드래그 복사 지원 ===== */
.select2-container .select2-selection__rendered {
user-select: text !important;
-webkit-user-select: text !important;
cursor: text;
padding-right: 36px !important;
}
/* x(초기화) 버튼을 드롭다운 화살표 왼쪽에 배치 */
#itemListTable .select2-selection__clear {
position: absolute !important;
right: 20px;
top: 50%;
transform: translateY(-50%);
font-size: 14px;
color: #999;
cursor: pointer;
user-select: none;
}
#itemListTable .select2-selection--single {
position: relative;
}
</style>
<script type="text/javascript">
// 품목 관리 변수
@@ -50,9 +108,103 @@
var hasProject = ("${hasProject}" === "Y");
var isMachine = ("${isMachine}" === "Y");
// ===== 컬럼 리사이즈 기능 =====
function fn_initColumnResize() {
var $table = $('#itemListTable');
if($table.length === 0) return;
// 각 th에 리사이저 핸들 추가
$table.find('thead th').each(function() {
if($(this).find('.col-resizer').length === 0) {
$(this).append('<div class="col-resizer"></div>');
}
});
var startX, startWidth, $th, colIndex, $col;
$(document).on('mousedown', '#itemListTable .col-resizer', function(e) {
$th = $(this).parent();
colIndex = $th.index();
$col = $table.find('colgroup col').eq(colIndex);
startX = e.pageX;
startWidth = $th.outerWidth();
$('body').css('cursor', 'col-resize');
$(document).on('mousemove.colResize', function(e) {
var newWidth = startWidth + (e.pageX - startX);
if(newWidth >= 40) {
$col.css('width', newWidth + 'px');
$th.css({'width': newWidth + 'px', 'min-width': newWidth + 'px'});
}
});
$(document).on('mouseup.colResize', function() {
$('body').css('cursor', '');
$(document).off('mousemove.colResize mouseup.colResize');
});
e.preventDefault();
e.stopPropagation();
});
}
// ===== Select2 드래그 복사 지원 =====
function fn_initSelect2DragCopy() {
var mouseTarget = null;
var wasDragged = false;
var startX = 0, startY = 0;
// select2:opening 상시 감시 — mouseTarget이 설정되어 있으면 열림 차단
$(document).on('select2:opening', '#itemListTable select', function(e) {
if(mouseTarget === this) {
e.preventDefault();
}
});
// capturing phase: Select2 핸들러보다 먼저 mouseTarget 플래그 설정
document.addEventListener('mousedown', function(e) {
var $sel = $(e.target).closest('#itemListTable .select2-selection');
if($sel.length === 0) return;
if($(e.target).hasClass('select2-selection__clear')) return;
var $container = $sel.closest('.select2-container');
var $select = $container.prev('select');
mouseTarget = $select[0]; // Select2 열림 차단 활성화
wasDragged = false;
startX = e.pageX;
startY = e.pageY;
var onMove = function(ev) {
if(Math.abs(ev.pageX - startX) > 3 || Math.abs(ev.pageY - startY) > 3) {
wasDragged = true;
}
};
var onUp = function() {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
if(!wasDragged) {
mouseTarget = null;
$select.select2('open');
}
setTimeout(function() { mouseTarget = null; }, 50);
};
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
}, true); // capturing phase — Select2보다 먼저 실행
}
$(function() {
// 반납사유 옵션을 템플릿에서 읽어옴
returnReasonOptions = $('#return_reason_template').html();
// 컬럼 리사이즈 초기화
fn_initColumnResize();
// Select2 드래그 복사 초기화
fn_initSelect2DragCopy();
// 기존 품목 데이터 로드
fn_loadExistingItems();

View File

@@ -36,6 +36,65 @@
#serial_no:-ms-input-placeholder {
color: #999 !important;
}
/* ===== 팝업 폼 전체 너비 확장 ===== */
section.business_popup_min_width {
padding: 0 !important;
margin: 0 auto !important;
width: calc(100% - 16px) !important;
}
#EntirePopupFormWrap {
width: 100% !important;
margin: 5px 0 0 0 !important;
}
/* ===== 품목 그리드 컬럼 리사이즈 ===== */
#EntirePopupFormWrap > table {
width: 100% !important;
}
#itemListTable {
table-layout: fixed;
width: 100%;
}
#itemListTable th {
position: relative;
user-select: none;
}
#itemListTable th .col-resizer {
position: absolute;
right: -4.5px;
top: 0;
width: 7px;
height: 100%;
cursor: col-resize;
z-index: 10;
}
#itemListTable th .col-resizer:hover {
background: rgba(0, 120, 215, 0.3);
}
/* ===== Select2 드래그 복사 지원 ===== */
.select2-container .select2-selection__rendered {
user-select: text !important;
-webkit-user-select: text !important;
cursor: text;
padding-right: 36px !important;
}
/* x(초기화) 버튼을 드롭다운 화살표 왼쪽에 배치 */
#itemListTable .select2-selection__clear {
position: absolute !important;
right: 20px;
top: 50%;
transform: translateY(-50%);
font-size: 14px;
color: #999;
cursor: pointer;
user-select: none;
}
#itemListTable .select2-selection--single {
position: relative;
}
</style>
<script type="text/javascript">
// 품목 관리 변수
@@ -50,10 +109,104 @@
// 프로젝트 존재 여부 체크 변수
var hasProject = false;
// ===== 컬럼 리사이즈 기능 =====
function fn_initColumnResize() {
var $table = $('#itemListTable');
if($table.length === 0) return;
// 각 th에 리사이저 핸들 추가
$table.find('thead th').each(function() {
if($(this).find('.col-resizer').length === 0) {
$(this).append('<div class="col-resizer"></div>');
}
});
var startX, startWidth, $th, colIndex, $col;
$(document).on('mousedown', '#itemListTable .col-resizer', function(e) {
$th = $(this).parent();
colIndex = $th.index();
$col = $table.find('colgroup col').eq(colIndex);
startX = e.pageX;
startWidth = $th.outerWidth();
$('body').css('cursor', 'col-resize');
$(document).on('mousemove.colResize', function(e) {
var newWidth = startWidth + (e.pageX - startX);
if(newWidth >= 40) {
$col.css('width', newWidth + 'px');
$th.css({'width': newWidth + 'px', 'min-width': newWidth + 'px'});
}
});
$(document).on('mouseup.colResize', function() {
$('body').css('cursor', '');
$(document).off('mousemove.colResize mouseup.colResize');
});
e.preventDefault();
e.stopPropagation();
});
}
// ===== Select2 드래그 복사 지원 =====
function fn_initSelect2DragCopy() {
var mouseTarget = null;
var wasDragged = false;
var startX = 0, startY = 0;
// select2:opening 상시 감시 — mouseTarget이 설정되어 있으면 열림 차단
$(document).on('select2:opening', '#itemListTable select', function(e) {
if(mouseTarget === this) {
e.preventDefault();
}
});
// capturing phase: Select2 핸들러보다 먼저 mouseTarget 플래그 설정
document.addEventListener('mousedown', function(e) {
var $sel = $(e.target).closest('#itemListTable .select2-selection');
if($sel.length === 0) return;
if($(e.target).hasClass('select2-selection__clear')) return;
var $container = $sel.closest('.select2-container');
var $select = $container.prev('select');
mouseTarget = $select[0]; // Select2 열림 차단 활성화
wasDragged = false;
startX = e.pageX;
startY = e.pageY;
var onMove = function(ev) {
if(Math.abs(ev.pageX - startX) > 3 || Math.abs(ev.pageY - startY) > 3) {
wasDragged = true;
}
};
var onUp = function() {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
if(!wasDragged) {
mouseTarget = null;
$select.select2('open');
}
setTimeout(function() { mouseTarget = null; }, 50);
};
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
}, true); // capturing phase — Select2보다 먼저 실행
}
$(function() {
// 반납사유 옵션을 템플릿에서 읽어옴
returnReasonOptions = $('#return_reason_template').html();
// 컬럼 리사이즈 초기화
fn_initColumnResize();
// Select2 드래그 복사 초기화
fn_initSelect2DragCopy();
//alert("${info.CATEGORY_CD}")
if("${info.CATEGORY_CD}" == '0000170' || "${info.CATEGORY_CD}" == '0000171'){//오버홀, 개조
$(".DIRECT").show();