판매/매출관리 S/N 조회를 CONTRACT_ITEM_OBJID 직접 매칭으로 변경

기존: CONTRACT_ITEM 을 (CONTRACT_OBJID + PART_OBJID) 로 JOIN 후 CIS 조회 →
      같은 계약/품번을 분할판매한 경우 형제 CONTRACT_ITEM 의 S/N 까지 섞여서 표시되는 버그
신규: CIS.ITEM_OBJID = PROJECT_MGMT.CONTRACT_ITEM_OBJID 직결 → 프로젝트별 본인 S/N 만 정확히 표시

productionplanning.xml 의 기존 패턴과 통일.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 15:12:15 +09:00
parent ced1e9e767
commit d47a52fcdf

View File

@@ -847,12 +847,11 @@
-- S/N: CONTRACT_ITEM_SERIAL(마스터) 우선, 없으면 판매등록 텍스트 fallback (콤마 구분 전체 목록)
COALESCE(
(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
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL),
FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL
AND CIS.SERIAL_NO != ''),
SR.serial_no
) AS SERIAL_NO,
-- 분할S/N: shipment_log에서 해당 프로젝트의 모든 분할S/N 집계
@@ -1016,13 +1015,10 @@
</if>
<if test="serialNo != null and serialNo != ''">
AND EXISTS (
SELECT 1 FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
SELECT 1 FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
)
</if>
<if test="orderStatus != null and orderStatus != ''">
@@ -1194,13 +1190,10 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
</if>
<if test="serialNo != null and serialNo != ''">
AND EXISTS (
SELECT 1 FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
SELECT 1 FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
)
</if>
<if test="orderStatus != null and orderStatus != ''">
@@ -1351,11 +1344,8 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
<if test="serialNo != null and serialNo != ''">
AND (
EXISTS (
SELECT 1 FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
SELECT 1 FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER('%' || #{serialNo} || '%')
)
@@ -1567,12 +1557,11 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
-- S/N: CONTRACT_ITEM_SERIAL(마스터) 우선, 전체 콤마 리스트 (판매등록 폼 파싱용)
COALESCE(
(SELECT STRING_AGG(CIS.SERIAL_NO, ', ' ORDER BY CIS.SERIAL_NO)
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
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL),
FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL
AND CIS.SERIAL_NO != ''),
SR.serial_no
) AS SERIAL_NO,
COALESCE(NULLIF(REPLACE(T.QUANTITY, ',', ''), '')::numeric, 0) AS ORDER_QUANTITY,
@@ -1723,11 +1712,11 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
-- 기존 S/N (CONTRACT_ITEM_SERIAL 마스터에서 조회)
COALESCE((
SELECT STRING_AGG(CIS2.SERIAL_NO, ',' ORDER BY CIS2.SEQ)
FROM CONTRACT_ITEM CI2
JOIN CONTRACT_ITEM_SERIAL CIS2 ON CI2.OBJID = CIS2.ITEM_OBJID AND CIS2.STATUS = 'ACTIVE'
WHERE CI2.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI2.PART_OBJID = PM.PART_OBJID
AND CI2.STATUS = 'ACTIVE'
FROM CONTRACT_ITEM_SERIAL CIS2
WHERE CIS2.ITEM_OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
AND UPPER(CIS2.STATUS) = 'ACTIVE'
AND CIS2.SERIAL_NO IS NOT NULL
AND CIS2.SERIAL_NO != ''
), '') AS SERIAL_NO
FROM PROJECT_MGMT PM
@@ -1805,13 +1794,11 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
) AS REQ_DEL_DATE,
-- S/N 조회 (CONTRACT_ITEM_SERIAL에서)
(SELECT STRING_AGG(CIS.SERIAL_NO, ', ' ORDER BY CIS.SERIAL_NO)
FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
WHERE CI.CONTRACT_OBJID = PM.CONTRACT_OBJID
AND CI.PART_OBJID = PM.PART_OBJID
AND CI.STATUS = 'ACTIVE'
FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL
AND CIS.SERIAL_NO != ''
) AS SERIAL_NO,
-- 고객요청사항 (CONTRACT_ITEM에서)
(SELECT CI.CUSTOMER_REQUEST
@@ -1994,10 +1981,12 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
COALESCE(SL.shipping_status, '미등록') AS shipping_order_status,
COALESCE((
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
JOIN PROJECT_MGMT PM ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID AND PM.PART_OBJID = CI.PART_OBJID
WHERE PM.PROJECT_NO = SL.target_objid AND CI.STATUS = 'ACTIVE'
FROM CONTRACT_ITEM_SERIAL CIS
JOIN PROJECT_MGMT PM ON CIS.ITEM_OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
WHERE PM.PROJECT_NO = SL.target_objid
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL
AND CIS.SERIAL_NO != ''
), '-') AS serial_no,
SL.target_objid AS project_no,
COALESCE(SL.split_serial_no, '-') AS split_serial_no,
@@ -2019,10 +2008,12 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
COALESCE(SL.shipping_method, '') AS SHIPPING_METHOD,
COALESCE((
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
JOIN PROJECT_MGMT PM ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID AND PM.PART_OBJID = CI.PART_OBJID
WHERE PM.PROJECT_NO = SL.target_objid AND CI.STATUS = 'ACTIVE'
FROM CONTRACT_ITEM_SERIAL CIS
JOIN PROJECT_MGMT PM ON CIS.ITEM_OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
WHERE PM.PROJECT_NO = SL.target_objid
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL
AND CIS.SERIAL_NO != ''
), '') AS SERIAL_NO,
COALESCE(SL.sales_unit_price, 0) AS SALES_UNIT_PRICE,
COALESCE(SL.sales_supply_price, 0) AS SALES_SUPPLY_PRICE,
@@ -2181,13 +2172,11 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
/* salesNcollectMgmt.getAllSerialNumbers - 프로젝트의 모든 S/N 조회 */
SELECT 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_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
JOIN CONTRACT_ITEM_SERIAL CIS ON CIS.ITEM_OBJID::VARCHAR = PM.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
WHERE PM.PROJECT_NO = #{projectNo}
AND CIS.SERIAL_NO IS NOT NULL
AND CIS.SERIAL_NO != ''
ORDER BY CIS.SERIAL_NO
</select>
@@ -2412,10 +2401,11 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
T.PART_NAME AS PRODUCT_NAME,
COALESCE((
SELECT STRING_AGG(CIS.SERIAL_NO, ',' ORDER BY CIS.SEQ)
FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID AND CIS.STATUS = 'ACTIVE'
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID AND CI.STATUS = 'ACTIVE'
FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND CIS.SERIAL_NO IS NOT NULL
AND CIS.SERIAL_NO != ''
), '') AS SERIAL_NO,
COALESCE(SL.split_serial_no, '') AS SPLIT_SERIAL_NO,
COALESCE(NULLIF(REPLACE(T.QUANTITY, ',', ''), '')::numeric, 0) AS ORDER_QUANTITY,
@@ -2482,13 +2472,10 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
</if>
<if test="serialNo != null and serialNo != ''">
AND EXISTS (
SELECT 1 FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
SELECT 1 FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
)
</if>
<if test="poNo != null and poNo != ''">
@@ -2573,13 +2560,10 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
</if>
<if test="serialNo != null and serialNo != ''">
AND EXISTS (
SELECT 1 FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID
AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
SELECT 1 FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER(CONCAT('%', #{serialNo}, '%'))
)
</if>
<if test="poNo != null and poNo != ''">
@@ -2649,10 +2633,9 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
</if>
<if test="serialNo != null and serialNo != ''">
AND EXISTS (
SELECT 1 FROM CONTRACT_ITEM CI
JOIN CONTRACT_ITEM_SERIAL CIS ON CI.OBJID = CIS.ITEM_OBJID
WHERE CI.CONTRACT_OBJID = T.CONTRACT_OBJID AND CI.PART_OBJID = T.PART_OBJID
AND CI.STATUS = 'ACTIVE' AND UPPER(CIS.STATUS) = 'ACTIVE'
SELECT 1 FROM CONTRACT_ITEM_SERIAL CIS
WHERE CIS.ITEM_OBJID::VARCHAR = T.CONTRACT_ITEM_OBJID
AND UPPER(CIS.STATUS) = 'ACTIVE'
AND UPPER(CIS.SERIAL_NO) LIKE UPPER('%' || #{serialNo} || '%')
)
</if>