Merge remote-tracking branch 'origin/main' into V2025120101

This commit is contained in:
2025-12-17 15:16:14 +09:00
16 changed files with 4724 additions and 270 deletions

View File

@@ -544,11 +544,14 @@
EFFECTIVE_DATE,
PAYMENT_TERMS,
REMARK,
REQUEST_CONTENT,
WRITER,
REGDATE,
STATUS,
SALES_REQUEST_OBJID,
SALES_MNG_USER_ID
SALES_MNG_USER_ID,
SALES_MNG_USER_ID2,
FORM_TYPE
,TITLE
,PURCHASE_DATE
,CONTRACT_MGMT_OBJID
@@ -562,6 +565,7 @@
,TOTAL_REAL_SUPPLY_PRICE
,DISCOUNT_PRICE
,TOTAL_PRICE
,TOTAL_PRICE_ALL
,NEGO_RATE
,SUPPLY_BUS_NO
,SUPPLY_USER_NAME
@@ -597,14 +601,17 @@
#{EFFECTIVE_DATE},
#{PAYMENT_TERMS},
#{REMARK},
#{REQUEST_CONTENT},
#{WRITER},
NOW(),
#{STATUS},
#{SALES_REQUEST_OBJID},
#{SALES_MNG_USER_ID}
#{SALES_MNG_USER_ID},
#{SALES_MNG_USER_ID2},
#{FORM_TYPE}
,#{TITLE}
,#{PURCHASE_DATE}
,#{CONTRACT_MGMT_OBJID}::NUMERIC
,#{CONTRACT_MGMT_OBJID}
,#{TYPE }
,#{INSPECT_METHOD }
,#{TOTAL_PRICE_TXT }
@@ -615,6 +622,7 @@
,#{TOTAL_REAL_SUPPLY_PRICE}
,#{DISCOUNT_PRICE }
,#{TOTAL_PRICE }
,#{TOTAL_PRICE_ALL }
,#{NEGO_RATE }
,#{SUPPLY_BUS_NO }
,#{SUPPLY_USER_NAME }
@@ -650,12 +658,17 @@
EFFECTIVE_DATE = #{EFFECTIVE_DATE},
PAYMENT_TERMS = #{PAYMENT_TERMS},
REMARK = #{REMARK},
REQUEST_CONTENT = #{REQUEST_CONTENT},
WRITER = #{WRITER},
STATUS = #{STATUS},
SALES_MNG_USER_ID = #{SALES_MNG_USER_ID}
SALES_MNG_USER_ID = #{SALES_MNG_USER_ID},
SALES_MNG_USER_ID2 = #{SALES_MNG_USER_ID2}
<if test="FORM_TYPE != null and FORM_TYPE != ''">
,FORM_TYPE = #{FORM_TYPE}
</if>
,TITLE = #{TITLE}
,PURCHASE_DATE = #{PURCHASE_DATE}
,CONTRACT_MGMT_OBJID = #{CONTRACT_MGMT_OBJID}::NUMERIC
,CONTRACT_MGMT_OBJID = #{CONTRACT_MGMT_OBJID}
,TYPE = #{TYPE }
,INSPECT_METHOD = #{INSPECT_METHOD }
,TOTAL_PRICE_TXT = #{TOTAL_PRICE_TXT }
@@ -669,6 +682,7 @@
,TOTAL_REAL_SUPPLY_PRICE = #{TOTAL_REAL_SUPPLY_PRICE}
,DISCOUNT_PRICE = #{DISCOUNT_PRICE }
,TOTAL_PRICE = #{TOTAL_PRICE }
,TOTAL_PRICE_ALL = #{TOTAL_PRICE_ALL }
,NEGO_RATE = #{NEGO_RATE }
,SUPPLY_BUS_NO = #{SUPPLY_BUS_NO }
,SUPPLY_USER_NAME = #{SUPPLY_USER_NAME }
@@ -736,7 +750,8 @@
REGDATE,
STATUS,
SALES_REQUEST_OBJID,
SALES_MNG_USER_ID
SALES_MNG_USER_ID,
FORM_TYPE
,TITLE
,PURCHASE_DATE
,CONTRACT_MGMT_OBJID
@@ -775,7 +790,8 @@
NOW(),
'create',
#{SALES_REQUEST_OBJID},
#{SALES_MNG_USER_ID}
#{SALES_MNG_USER_ID},
#{FORM_TYPE}
,#{TITLE}
,#{PURCHASE_DATE}
,NULLIF(#{PROJECT_NO}::TEXT, '')::NUMERIC
@@ -813,7 +829,7 @@
SALES_MNG_USER_ID = #{SALES_MNG_USER_ID}
,TITLE = #{TITLE}
,PURCHASE_DATE = #{PURCHASE_DATE}
,CONTRACT_MGMT_OBJID = NULLIF(#{CONTRACT_MGMT_OBJID}::TEXT, '')::NUMERIC
,CONTRACT_MGMT_OBJID = #{CONTRACT_MGMT_OBJID}
,TYPE = #{TYPE }
,INSPECT_METHOD = #{INSPECT_METHOD }
,TOTAL_PRICE_TXT = #{TOTAL_PRICE_TXT }
@@ -970,7 +986,7 @@
#{SALES_MNG_USER_ID}
,#{TITLE}
,#{PURCHASE_DATE}
,#{CONTRACT_MGMT_OBJID}::NUMERIC
,#{CONTRACT_MGMT_OBJID}
,#{TYPE }
,#{INSPECT_METHOD }
,#{TOTAL_PRICE_TXT }
@@ -1157,6 +1173,10 @@
,STOCK_QTY
,REAL_ORDER_QTY
,REAL_SUPPLY_PRICE
,PART_DELIVERY_PLACE
,PRODUCT_NAME
,WORK_ORDER_NO
,DELIVERY_REQUEST_DATE
)
VALUES
(
@@ -1196,6 +1216,10 @@
,REPLACE(#{STOCK_QTY} ::VARCHAR, ',', '')
,REPLACE(#{REAL_ORDER_QTY} ::VARCHAR, ',', '')
,REPLACE(#{REAL_SUPPLY_PRICE} ::VARCHAR, ',', '')
,#{PART_DELIVERY_PLACE}
,#{PRODUCT_NAME}
,#{WORK_ORDER_NO}
,#{DELIVERY_REQUEST_DATE}
) ON CONFLICT (OBJID) DO
UPDATE
SET
@@ -1223,6 +1247,10 @@
,STOCK_QTY = REPLACE(#{STOCK_QTY} ::VARCHAR, ',', '')
,REAL_ORDER_QTY = REPLACE(#{REAL_ORDER_QTY} ::VARCHAR, ',', '')
,REAL_SUPPLY_PRICE = REPLACE(#{REAL_SUPPLY_PRICE} ::VARCHAR, ',', '')
,PART_DELIVERY_PLACE = #{PART_DELIVERY_PLACE}
,PRODUCT_NAME = #{PRODUCT_NAME}
,WORK_ORDER_NO = #{WORK_ORDER_NO}
,DELIVERY_REQUEST_DATE = #{DELIVERY_REQUEST_DATE}
</update>
<select id="getMyCompanyInfo" parameterType="map" resultType="map">
@@ -1377,6 +1405,22 @@
,(SELECT PURCHASE_ORDER_NO FROM PURCHASE_ORDER_MASTER SPOM WHERE SPOM.OBJID = POM.PURCHASE_ORDER_NO_ORG) PURCHASE_ORDER_NO_ORG_NO
,POM.SALES_STATUS
,POM.RECEPTION_STATUS
-- 담당자1 정보 (일반발주서용)
,(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID) AS MANAGER_NAME
,(SELECT POSITION_NAME FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID) AS MANAGER_POSITION
,(SELECT CELL_PHONE FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID) AS MANAGER_PHONE
,(SELECT EMAIL FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID) AS MANAGER_EMAIL
-- 담당자2 정보 (일반발주서용)
,POM.SALES_MNG_USER_ID2
,(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID2) AS MANAGER_NAME2
,(SELECT POSITION_NAME FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID2) AS MANAGER_POSITION2
,(SELECT CELL_PHONE FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID2) AS MANAGER_PHONE2
,(SELECT EMAIL FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID2) AS MANAGER_EMAIL2
-- 요청사항
,POM.REQUEST_CONTENT
FROM
PURCHASE_ORDER_MASTER POM
@@ -2059,6 +2103,7 @@
WHERE OBJID = #{OBJID}
</update>
<!-- 자재(RESOURCE_MNG) 생성 - 중복 시 무시 -->
<insert id="insertResourceMasterMng" parameterType="map">
INSERT INTO RESOURCE_MNG
(
@@ -2074,24 +2119,21 @@
REGDATE,
WRITER
)
SELECT
VALUES
(
#{OBJID}::NUMERIC,
#{PART_OBJID},
#{LD_PART_OBJID},
(SELECT PM.PART_NAME FROM PART_MNG PM WHERE 1=1 AND PM.OBJID::VARCHAR = #{PART_OBJID}::VARCHAR),
(SELECT PM.PART_NAME FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = #{PART_OBJID}::VARCHAR),
#{SPEC},
(SELECT PM.MATERIAL FROM PART_MNG PM WHERE 1=1 AND PM.OBJID::VARCHAR = #{PART_OBJID}::VARCHAR),
(SELECT PM.MATERIAL FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = #{PART_OBJID}::VARCHAR),
#{MAKER},
#{UNIT},
(SELECT PM.WEIGHT FROM PART_MNG PM WHERE 1=1 AND PM.OBJID::VARCHAR = #{PART_OBJID}::VARCHAR),
(SELECT PM.WEIGHT FROM PART_MNG PM WHERE PM.OBJID::VARCHAR = #{PART_OBJID}::VARCHAR),
NOW(),
#{WRITER}
WHERE
NOT EXISTS(
SELECT 1 FROM RESOURCE_MNG WHERE PART_OBJID = #{PART_OBJID}
UNION ALL
SELECT 1 FROM RESOURCE_MNG WHERE LD_PART_OBJID = #{LD_PART_OBJID}
)
)
ON CONFLICT (PART_OBJID) DO NOTHING
</insert>
<!-- 마지막 재고 정보를 가져온다. -->
@@ -2227,6 +2269,8 @@
,(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = T.UNIT) AS UNIT_NAME
,P.PART_NO P_PART_NO
,POM.BOM_REPORT_OBJID
,POM.PURCHASE_ORDER_NO
,(SELECT CLIENT_NM FROM CLIENT_MNG WHERE OBJID::varchar = POM.PARTNER_OBJID) AS PARTNER_NAME
FROM PURCHASE_ORDER_PART T
INNER JOIN PURCHASE_ORDER_MASTER POM
ON POM.OBJID = T.PURCHASE_ORDER_MASTER_OBJID
@@ -2376,25 +2420,20 @@
WHERE OBJID = #{objId} OR MULTI_MASTER_OBJID = #{objId}
</delete>
<!-- 공급처 정보 조회 (CLIENT_MNG 테이블) -->
<select id="purchaseOrderAdminSupplyInfo" parameterType="map" resultType="map">
SELECT
T1.OBJID
,T1.BUS_REG_NO AS SUPPLY_BUS_NO
,(CASE WHEN T2.OBJID IS NULL THEN T1.CHARGE_USER_NAME ELSE T2.CHARGER_NAME END) AS SUPPLY_USER_NAME
,(CASE WHEN T2.OBJID IS NULL THEN T1.SUPPLY_TEL_NO ELSE T2.PHONE END) AS SUPPLY_USER_HP
,(CASE WHEN T2.OBJID IS NULL THEN T1.OFFICE_NO ELSE T2.TEL END) AS SUPPLY_USER_TEL
,(CASE WHEN T2.OBJID IS NULL THEN T1.SUPPLY_FAX_NO ELSE T2.FAX END) AS SUPPLY_USER_FAX
,(CASE WHEN T2.OBJID IS NULL THEN T1.EMAIL ELSE T2.EMAIL END) AS SUPPLY_USER_EMAIL
,T1.SUPPLY_ADDRESS AS SUPPLY_ADDR
FROM ADMIN_SUPPLY_MNG AS T1
LEFT OUTER JOIN
(SELECT * FROM (SELECT DENSE_RANK() OVER(PARTITION BY T.SUPPLY_OBJID ORDER BY T.CHARGER_NAME ASC) AS TOP, T.*
FROM SUPPLY_CHARGER_MNG T WHERE CHARGER_TYPE = '0000330' /*발주서공급처담당*/
) AS T WHERE TOP = 1
) AS T2
ON T1.OBJID = T2.SUPPLY_OBJID::NUMERIC
,T1.CEO_NM AS SUPPLY_USER_NAME
,T1.VENDOR_MOBILE AS SUPPLY_USER_HP
,T1.TEL_NO AS SUPPLY_USER_TEL
,T1.FAX_NO AS SUPPLY_USER_FAX
,T1.EMAIL AS SUPPLY_USER_EMAIL
,CONCAT(COALESCE(T1.ADDR1,''), ' ', COALESCE(T1.ADDR2,'')) AS SUPPLY_ADDR
FROM CLIENT_MNG AS T1
WHERE 1=1
AND T1.OBJID = #{PARTNER_OBJID}::NUMERIC
AND T1.OBJID::VARCHAR = #{PARTNER_OBJID}::VARCHAR
</select>
<select id="purchaseOrderSalesBomPartListByPartnerContract" parameterType="map" resultType="map">
@@ -3164,10 +3203,11 @@ SELECT POM.OBJID
,(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = POM.TYPE) AS TYPE_NAME
,POM.PARTNER_OBJID
,CASE
,(SELECT CLIENT_NM FROM CLIENT_MNG WHERE OBJID::VARCHAR = POM.PARTNER_OBJID) AS PARTNER_NAME
<!-- ,CASE
WHEN POM.PARTNER_OBJID LIKE 'C_%' THEN (SELECT CLIENT_NM FROM CLIENT_MNG WHERE 'C_' || OBJID::VARCHAR = POM.PARTNER_OBJID)
ELSE (SELECT SUPPLY_NAME FROM ADMIN_SUPPLY_MNG WHERE 1=1 AND OBJID::VARCHAR = POM.PARTNER_OBJID)
END AS PARTNER_NAME
END AS PARTNER_NAME -->
,POM.SALES_MNG_USER_ID
,(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID) AS SALES_MNG_USER_NAME
@@ -3196,6 +3236,7 @@ SELECT POM.OBJID
,POM.MAIL_SEND_YN
,POM.MAIL_SEND_DATE
,POM.STATUS
,COALESCE(POM.FORM_TYPE, 'general') AS FORM_TYPE
,A.APPR_STATUS
,CASE WHEN POM.STATUS = 'cancel' then '취소'
ELSE COALESCE(A.APPR_STATUS_NAME,'작성중')
@@ -3265,7 +3306,7 @@ SELECT POM.OBJID
ON POM.CONTRACT_MGMT_OBJID = CM.OBJID
left outer join SALES_REQUEST_MASTER as SRM
on POM.SALES_REQUEST_OBJID = SRM.OBJID
-- and SRM.DOC_TYPE = 'PROPOSAL' -- DOC_TYPE 컬럼 없음, 주석처리
and SRM.DOC_TYPE = 'PROPOSAL'
<!-- 230907 outer join으로 변경
,PROJECT_MGMT AS CM
WHERE POM.CONTRACT_MGMT_OBJID = CM.OBJID
@@ -3647,7 +3688,7 @@ SELECT OBJID
, FILE_SIZE
, FILE_EXT
, UPPER(FILE_EXT) UPPER_FILE_EXT
, REPLACE(FILE_PATH, '\', '\\') AS FILE_PATH
, REPLACE(FILE_PATH, '\', '/') AS FILE_PATH
, WRITER
, (SELECT USER_NAME FROM USER_INFO USER_INFO_T WHERE USER_INFO_T.USER_ID = WRITER) AS USER_NAME
, (SELECT DEPT_NAME FROM USER_INFO USER_INFO_T WHERE USER_INFO_T.USER_ID = WRITER) AS DEPT_NAME
@@ -4202,10 +4243,29 @@ SELECT POM.OBJID
,POM.DELIVERY_DATE
,POM.PARTNER_OBJID
,CASE
WHEN POM.PARTNER_OBJID LIKE 'C_%' THEN (SELECT CLIENT_NM FROM CLIENT_MNG WHERE 'C_' || OBJID::VARCHAR = POM.PARTNER_OBJID)
ELSE (SELECT SUPPLY_NAME FROM ADMIN_SUPPLY_MNG WHERE 1=1 AND OBJID::VARCHAR = POM.PARTNER_OBJID)
END AS PARTNER_NAME
,(SELECT CLIENT_NM FROM CLIENT_MNG WHERE OBJID::VARCHAR = POM.PARTNER_OBJID) AS PARTNER_NAME
<!-- 품의서 번호 -->
,POM.SALES_REQUEST_OBJID
,(SELECT REQUEST_MNG_NO FROM SALES_REQUEST_MASTER WHERE OBJID::VARCHAR = POM.SALES_REQUEST_OBJID) AS PROPOSAL_NO
<!-- 품번/품명 (첫번째 + 외 N건) -->
,(SELECT
CASE
WHEN COUNT(*) > 1 THEN MIN(POP.PART_NO) || ' 외 ' || (COUNT(*) - 1) || '건'
ELSE MIN(POP.PART_NO)
END
FROM PURCHASE_ORDER_PART POP
WHERE POP.PURCHASE_ORDER_MASTER_OBJID = POM.OBJID::VARCHAR
) AS PART_NO
,(SELECT
CASE
WHEN COUNT(*) > 1 THEN MIN(POP.PART_NAME) || ' 외 ' || (COUNT(*) - 1) || '건'
ELSE MIN(POP.PART_NAME)
END
FROM PURCHASE_ORDER_PART POP
WHERE POP.PURCHASE_ORDER_MASTER_OBJID = POM.OBJID::VARCHAR
) AS PART_NAME
,POM.SALES_MNG_USER_ID
,(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = POM.SALES_MNG_USER_ID) AS SALES_MNG_USER_NAME
@@ -4227,9 +4287,9 @@ SELECT POM.OBJID
<!-- ,S1.TOTAL_DEFECT_QTY -->
<!-- ,(CASE WHEN 0 <![CDATA[ >= ]]> ((SELECT SUM(ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) - (S1.TOTAL_DELIVERY_QTY - S1.TOTAL_DEFECT_QTY)) THEN '입고완료' -->
<!-- ,((SELECT SUM(ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) - (S1.TOTAL_DELIVERY_QTY - S1.TOTAL_DEFECT_QTY )) AS NON_DELIVERY_QTY -->
,((SELECT SUM(REAL_ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) - (S1.TOTAL_DELIVERY_QTY )) AS NON_DELIVERY_QTY
,((SELECT SUM(ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) - (S1.TOTAL_DELIVERY_QTY )) AS NON_DELIVERY_QTY
<!-- ,S1.TOTAL_DEFECT_QTY -->
,(CASE WHEN 0 <![CDATA[ >= ]]> ((SELECT SUM(REAL_ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) - (S1.TOTAL_DELIVERY_QTY <!-- - S1.TOTAL_DEFECT_QTY -->)) THEN '입고완료'
,(CASE WHEN 0 <![CDATA[ >= ]]> ((SELECT SUM(ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) - (S1.TOTAL_DELIVERY_QTY <!-- - S1.TOTAL_DEFECT_QTY -->)) THEN '입고완료'
WHEN TO_CHAR(NOW(),'YYYY-MM-DD') <![CDATA[ > ]]> POM.DELIVERY_DATE THEN '지연'
ELSE '입고중'
END) AS DELIVERY_STATUS
@@ -4238,6 +4298,7 @@ SELECT POM.OBJID
,POM.ORDER_TYPE_CD
,(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = POM.ORDER_TYPE_CD) AS ORDER_TYPE_CD_NAME
,(SELECT user_name(RECEIVER_ID) FROM ARRIVAL_PLAN AP WHERE AP.parent_objid = POM.OBJID ORDER BY AP.RECEIPT_DATE desc LIMIT 1) AS CUR_RECEIVER_NAME
,(SELECT COUNT(1) FROM ATTACH_FILE_INFO AF WHERE AF.TARGET_OBJID = POM.OBJID AND AF.DOC_TYPE = 'INSPECTION_FILE' AND UPPER(AF.STATUS) = 'ACTIVE') AS INSPECTION_FILE_CNT
<!-- ,A.APPR_STATUS_NAME -->
FROM PURCHASE_ORDER_MASTER AS POM
<!-- LEFT OUTER JOIN(
@@ -6008,4 +6069,26 @@ FROM(
WHERE OBJID = #{OBJID}
</update>
<!-- 입고관리 데이터 드롭다운용 조회 (반제품검사 팝업에서 사용) -->
<!-- ARRIVAL_PLAN 테이블에서 입고완료된 품목 조회 (1차+2차 합산) -->
<select id="getDeliveryListForDropdown" parameterType="map" resultType="map">
SELECT
AP.ORDER_PART_OBJID AS OBJID
,AP.PART_OBJID
,COALESCE(CASE WHEN POM.TYPE IN ('0001070','0001069') THEN PM.PART_NO ELSE POP.PART_NO END, PM.PART_NO, '') AS PART_NO
,COALESCE(POP.PART_NAME, PM.PART_NAME, '') AS PART_NAME
,COALESCE(POP.PART_NAME, PM.PART_NAME, '') AS MODEL_NAME
,COALESCE(POM.PURCHASE_ORDER_NO, '') AS WORK_ORDER_NO
,COALESCE(SUM(AP.RECEIPT_QTY::NUMERIC), 0) AS RECEIPT_QTY
FROM ARRIVAL_PLAN AP
LEFT JOIN PURCHASE_ORDER_PART POP ON POP.OBJID = AP.ORDER_PART_OBJID
LEFT JOIN PART_MNG PM ON PM.OBJID::VARCHAR = AP.PART_OBJID OR PM.OBJID = POP.PART_OBJID
LEFT JOIN PURCHASE_ORDER_MASTER POM ON POM.OBJID = AP.PARENT_OBJID
WHERE AP.RECEIPT_QTY IS NOT NULL
AND AP.RECEIPT_QTY::NUMERIC > 0
AND AP.INVENTORY_STATUS = 'Y'
GROUP BY AP.ORDER_PART_OBJID, AP.PART_OBJID, POP.PART_NO, POP.PART_NAME, PM.PART_NO, PM.PART_NAME, POM.PURCHASE_ORDER_NO, POM.TYPE
ORDER BY PART_NO
</select>
</mapper>

File diff suppressed because it is too large Load Diff

View File

@@ -67,6 +67,11 @@ $(document).ready(function(){
fn_registResultPopUp();
});
// 결재상신
$("#btnApproval").click(function(){
fn_approval();
});
fn_search();
});
@@ -217,6 +222,35 @@ function fn_FileRegist(objId, docType, docTypeName){
fn_centerPopup(popup_width, popup_height, url);
}
// 결재상신
function fn_approval(){
var selected = _tabulGrid.getSelectedData();
if(selected.length == 0){
Swal.fire("결재상신할 데이터를 선택해주세요.");
return;
}
if(selected.length > 1){
Swal.fire("한번에 한개의 결재만 가능합니다.");
return;
}
var title = fnc_checkNull(selected[0].ECR_NO) + " " + fnc_checkNull(selected[0].PART_NO);
var objId = fnc_checkNull(selected[0].OBJID);
Swal.fire({
title: '결재상신',
text: '결재상신 하시겠습니까?',
icon: 'question',
showCancelButton: true,
confirmButtonText: '확인',
cancelButtonText: '취소'
}).then((result) => {
if(result.isConfirmed){
window.open("/approval/registApproval.do?targetType=ECR&targetObjId="+objId+"&approvalTitle="+encodeURIComponent(title)+"&callbackFnc=fn_search","registApproval","width=700,height=700");
}
});
}
</script>
<body>
@@ -233,6 +267,7 @@ function fn_FileRegist(objId, docType, docTypeName){
<span><%=menuName%></span>
</h2>
<div class="btnArea">
<input type="button" class="plm_btns" value="결재상신" id="btnApproval">
<input type="button" class="plm_btns" value="ECR 등록" id="btnRegistEcr">
<input type="button" class="plm_btns" value="ECR 결과등록" id="btnRegistResult">
<input type="button" class="plm_btns" value="조회" id="btnSearch">

View File

@@ -204,12 +204,14 @@ function fn_save(){
<textarea name="ISSUE_CONTENT" id="ISSUE_CONTENT" rows="4" style="width:100%;" required reqTitle="이슈사항" type="text">${info.issue_content}</textarea>
</td>
</tr>
<!-- 비고 주석처리
<tr>
<td class="input_title"><label>비고</label></td>
<td colspan="3">
<textarea name="REMARK" id="REMARK" rows="2" style="width:100%;">${info.remark}</textarea>
</td>
</tr>
-->
</table>
</div>

View File

@@ -353,13 +353,7 @@ function fn_save(){
<tr>
<td class="input_title"><label>이슈사항</label></td>
<td colspan="3">
<textarea rows="4" style="width:100%;" readonly>${info.issue_content}</textarea>
</td>
</tr>
<tr>
<td class="input_title"><label>비고</label></td>
<td colspan="3">
<textarea rows="2" style="width:100%;" readonly>${info.remark}</textarea>
<textarea rows="10" style="width:100%;" readonly>${info.issue_content}</textarea>
</td>
</tr>
</table>

View File

@@ -76,11 +76,6 @@ $(document).ready(function(){
fn_requestPopUp();
});
// 엑셀 다운로드
$("#btnExcel").click(function(){
fn_excelDownload();
});
fn_search();
});
@@ -184,14 +179,7 @@ function fn_formPopUp(objId){
hiddenForm.submit();
}
// 엑셀 다운로드
function fn_excelDownload(){
var form = document.form1;
form.action = "/quality/incomingInspectionExcelDownload.do";
form.submit();
form.action = "";
}
// 입고결과 조회 팝업 (view 전용)
function fn_deliveryAcceptanceViewPopUp(objId,DELIVERY_STATUS){
var popup_width = 1560;
var popup_height = 1050;
@@ -229,7 +217,6 @@ function fn_deliveryAcceptanceViewPopUp(objId,DELIVERY_STATUS){
<div class="btnArea">
<input type="button" class="plm_btns" value="수입검사 요청" id="btnRequest">
<input type="button" class="plm_btns" value="조회" id="btnSearch">
<input type="button" class="plm_btns excel" value="Excel Download" id="btnExcel">
</div>
</div>

View File

@@ -83,11 +83,6 @@ $(document).ready(function(){
fn_registPopUp();
});
// 엑셀 다운로드
$("#btnExcel").click(function(){
fn_excelDownload();
});
fn_search();
});
@@ -156,13 +151,6 @@ function fn_registPopUp(){
window.open(url, "processInspectionPopUp", "width=" + popup_width + ",height=" + popup_height + ",scrollbars=yes,resizable=yes");
}
// 엑셀 다운로드
function fn_excelDownload(){
var form = document.form1;
form.action = "/quality/processInspectionExcelDownload.do";
form.submit();
form.action = "";
}
</script>
<body>
@@ -181,7 +169,6 @@ function fn_excelDownload(){
<div class="btnArea">
<input type="button" class="plm_btns" value="공정검사 등록" id="btnRegist">
<input type="button" class="plm_btns" value="조회" id="btnSearch">
<input type="button" class="plm_btns excel" value="Excel Download" id="btnExcel">
</div>
</div>

View File

@@ -0,0 +1,96 @@
<%@ page isThreadSafe = "true" %>
<%@ page buffer="256kb" %>
<%@ page autoFlush = "true" %>
<%@ page contentType="application/vnd.ms-excel;charset=UTF-8" %>
<%@ page import="com.pms.common.utils.*"%>
<%@ page import="java.util.*" %>
<%
java.text.SimpleDateFormat frm= new java.text.SimpleDateFormat ("yyyy_MM_dd_HH_mm");
Calendar cal = Calendar.getInstance();
String todayKor = frm.format(cal.getTime());
String excelName = "품질관리_반제품검사관리";
String encodeName = excelName + todayKor + ".xls";
String fileName = java.net.URLEncoder.encode(encodeName,"UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
response.setHeader("Content-Description", "JSP Generated Data");
List list = (List)request.getAttribute("LIST");
%>
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=UTF-8">
<meta name=ProgId content=Excel.Sheet>
<meta name=Generator content="Microsoft Excel 11">
<title><%=Constants.SYSTEM_NAME%></title>
</head>
<body class="backcolor">
<form name="form1" action="" method="post">
<section class="min_part_search">
<div class="pdm_menu_name">
<h2>
<span>반제품검사 관리</span>
</h2>
</div>
<div class="contents_page_basic_margin">
<div class="pdm_table_wrap">
<table class="pdm_table_noImg" style="text-align:center;" border="1">
<tr class="pdm_thead" align="center" style="background:yellow; font-weight:bold;">
<td>No.</td>
<td>품명(모델명)</td>
<td>제품구분</td>
<td>작업지시번호</td>
<td>부품품번</td>
<td>부품명</td>
<td>입고수량</td>
<td>양품수량</td>
<td>불량수량</td>
<td>불량율(%)</td>
<td>불량유형</td>
<td>불량원인</td>
<td>귀책부서</td>
<td>처리현황</td>
<td>검사일</td>
<td>검사자</td>
<td>처리결과</td>
<td>비고</td>
<td>데이터타입</td>
</tr>
<%
if(list != null && !list.isEmpty()){
for(int i = 0 ; i < list.size() ; i++){
Map map = (Map)list.get(i);
%>
<tr>
<td align="center"><%=i+1%></td>
<td align="left"><%=CommonUtils.checkNull(map.get("model_name"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("product_type"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("work_order_no"))%></td>
<td align="left"><%=CommonUtils.checkNull(map.get("part_no"))%></td>
<td align="left"><%=CommonUtils.checkNull(map.get("part_name"))%></td>
<td align="right"><%=CommonUtils.checkNull(map.get("receipt_qty"))%></td>
<td align="right"><%=CommonUtils.checkNull(map.get("good_qty"))%></td>
<td align="right"><%=CommonUtils.checkNull(map.get("defect_qty"))%></td>
<td align="right"><%=CommonUtils.checkNull(map.get("defect_rate"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("defect_type"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("defect_cause"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("responsible_dept"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("process_status"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("inspection_date"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("writer_name"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("disposition_type"))%></td>
<td align="left"><%=CommonUtils.checkNull(map.get("remark"))%></td>
<td align="center"><%=CommonUtils.checkNull(map.get("data_type"))%></td>
</tr>
<%
}
}
%>
</table>
</div>
</div>
</section>
</form>
</body>
</html>

View File

@@ -18,15 +18,45 @@ String menuName = CommonUtils.getMenuName(menuObjId, "반제품검사 관리");
</head>
<style>
.select2-selection__choice {
font-size: 11px;
background-color: #fff !important;
border: none !important;
margin-right: 0px !important;
}
.select2-selection__choice__remove {
display: contents !important;
}
.select2-container .select2-selection--multiple {
min-height: 20px !important;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
margin-top: 3.5px !important;
}
.select2-selection__rendered {
height: 18px !important;
}
.select2-container .select2-selection--multiple .select2-selection__rendered {
overflow: auto !important;
}
/* 검사결과 스타일 */
.status-discard { color: #dc3545; font-weight: bold; }
.status-modify { color: #ffc107; font-weight: bold; }
.status-special { color: #28a745; font-weight: bold; }
body, html {
overflow-x: hidden;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script type="text/javascript">
$(document).ready(function(){
fnc_changePaginationAndTotalCountArea();
$('.select2').select2();
fnc_datepick();
$("input").keyup(function(e){
if(e.keyCode == 13){
@@ -46,7 +76,7 @@ $(document).ready(function(){
fn_registPopUp();
});
// 엑셀 다운로드
// 엑셀 다운로드 (원본 데이터)
$("#btnExcel").click(function(){
fn_excelDownload();
});
@@ -54,24 +84,187 @@ $(document).ready(function(){
fn_search();
});
// 컬럼: 프로젝트번호, 작업지시번호, 품번, 품명, 입고수량, 폐기/수정/특채
// 엑셀 다운로드 (원본 데이터 - 외 N건 풀어서)
function fn_excelDownload(){
// 서버에서 원본 데이터 가져오기
var params = {
search_model_name: $("#search_model_name").val() || "",
search_work_order_no: $("#search_work_order_no").val() || "",
search_part_no: $("#search_part_no").val() || "",
search_part_name: $("#search_part_name").val() || "",
search_inspection_date: $("#search_inspection_date").val() || "",
search_writer: $("#search_writer").val() || ""
};
$.ajax({
url: "/quality/getSemiProductInspectionListForExcel.do",
type: "POST",
data: params,
dataType: "json",
success: function(result){
if(result && result.list && result.list.length > 0){
createExcelFile(result.list);
} else {
Swal.fire("다운로드할 데이터가 없습니다.");
}
},
error: function(xhr, status, error){
console.error("엑셀 데이터 조회 실패:", error);
Swal.fire("엑셀 데이터 조회 중 오류가 발생했습니다.");
}
});
}
// ExcelJS로 원본 데이터 엑셀 파일 생성 (공통 스타일 적용)
async function createExcelFile(data){
var pageTitle = "반제품검사관리";
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet(pageTitle);
// 헤더 설정
var headers = ["No", "품명(모델명)", "제품구분", "작업지시번호", "부품품번", "부품명",
"입고수량 합계", "양품수량 합계", "불량수량 합계", "불량율(%)", "재생수량 합계", "최종양품수량 합계",
"검사일", "검사자", "불량유형", "불량원인", "귀책부서", "처리현황", "처리결과", "비고"];
// 열 너비 설정
var colWidths = [6, 25, 12, 18, 20, 25, 15, 15, 15, 12, 15, 18, 12, 12, 15, 15, 12, 12, 12, 20];
colWidths.forEach(function(width, idx){
worksheet.getColumn(idx + 1).width = width;
});
// 제목 행 추가
worksheet.mergeCells('A1:T1');
var titleCell = worksheet.getCell('A1');
titleCell.value = pageTitle;
titleCell.font = { size: 16, bold: true };
titleCell.alignment = { vertical: 'middle', horizontal: 'center' };
worksheet.getRow(1).height = 30;
// 빈 행 추가
worksheet.addRow([]);
// 헤더 행 추가 (3행)
var headerRow = worksheet.addRow(headers);
// 헤더 스타일 (공통 스타일: 파란색 배경, 흰색 글자)
headerRow.eachCell(function(cell){
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FF4472C4' } // 파란색
};
cell.font = {
color: { argb: 'FFFFFFFF' }, // 흰색 글자
bold: true
};
cell.alignment = {
vertical: 'middle',
horizontal: 'center',
wrapText: true
};
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
};
});
headerRow.height = 25;
// 데이터 추가
data.forEach(function(item, index){
var row = worksheet.addRow([
index + 1,
item.model_name || item.MODEL_NAME || "",
item.product_type || item.PRODUCT_TYPE || "",
item.work_order_no || item.WORK_ORDER_NO || "",
item.part_no || item.PART_NO || "",
item.part_name || item.PART_NAME || "",
item.receipt_qty || item.RECEIPT_QTY || 0,
item.good_qty || item.GOOD_QTY || 0,
item.defect_qty || item.DEFECT_QTY || 0,
item.defect_rate || item.DEFECT_RATE || 0,
item.regeneration_qty || item.REGENERATION_QTY || 0,
item.final_good_qty || item.FINAL_GOOD_QTY || 0,
item.inspection_date || item.INSPECTION_DATE || "",
item.writer_name || item.WRITER_NAME || "",
item.defect_type || item.DEFECT_TYPE || "",
item.defect_cause || item.DEFECT_CAUSE || "",
item.responsible_dept || item.RESPONSIBLE_DEPT || "",
item.process_status || item.PROCESS_STATUS || "",
item.disposition_type || item.DISPOSITION_TYPE || "",
item.remark || item.REMARK || ""
]);
// 데이터 행 스타일 (테두리)
row.eachCell(function(cell, colNumber){
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
};
// 숫자 컬럼 오른쪽 정렬 (7~12번 컬럼: 수량, 불량율)
if(colNumber >= 7 && colNumber <= 12){
cell.alignment = { horizontal: 'right' };
// 숫자에 천단위 구분자 (불량율 제외)
if(colNumber !== 10 && typeof cell.value === 'number'){
cell.numFmt = '#,##0';
}
} else if(colNumber === 1){
cell.alignment = { horizontal: 'center' };
}
});
});
// 파일명 생성
var date = new Date();
var currentDate = date.getFullYear() +
("0" + (date.getMonth() + 1)).slice(-2) +
("0" + date.getDate()).slice(-2) + "_" +
("0" + date.getHours()).slice(-2) +
("0" + date.getMinutes()).slice(-2);
var fileName = pageTitle + "_" + currentDate + ".xlsx";
// 다운로드
const buffer = await workbook.xlsx.writeBuffer();
saveAs(new Blob([buffer]), fileName);
}
// 컬럼: 품명(모델명), 작업지시번호, 부품품번, 부품명, 입고수량 합계, 양품수량 합계, 불량수량 합계, 불량율, 재생수량 합계, 최종 양품수량 합계, 검사일, 검사자
var columns = [
{headerHozAlign:'center', hozAlign:'center', minWidth:140, widthGrow:1, title:'프로젝트번호', field:'PROJECT_NO'},
{headerHozAlign:'center', hozAlign:'left', minWidth:150, widthGrow:2, title:'품명(모델명)', field:'MODEL_NAME'},
{headerHozAlign:'center', hozAlign:'center', minWidth:140, widthGrow:1, title:'작업지시번호', field:'WORK_ORDER_NO'},
{headerHozAlign:'center', hozAlign:'left', minWidth:150, widthGrow:2, title:'품번', field:'PART_NO'},
{headerHozAlign:'center', hozAlign:'left', minWidth:200, widthGrow:3, title:'품명', field:'PART_NAME'},
{headerHozAlign:'center', hozAlign:'right', minWidth:100, widthGrow:1, title:'입고수량', field:'RECEIPT_QTY',
{headerHozAlign:'center', hozAlign:'left', minWidth:150, widthGrow:2, title:'부품품번', field:'PART_NO'},
{headerHozAlign:'center', hozAlign:'left', minWidth:200, widthGrow:3, title:'품명', field:'PART_NAME'},
{headerHozAlign:'center', hozAlign:'right', minWidth:120, widthGrow:1, title:'입고수량 합계', field:'RECEIPT_QTY',
formatter:"money", formatterParams:{thousand:",", precision:false}
},
{headerHozAlign:'center', hozAlign:'center', minWidth:120, widthGrow:1, title:'폐기/수정/특채', field:'DISPOSITION_TYPE',
{headerHozAlign:'center', hozAlign:'right', minWidth:120, widthGrow:1, title:'양품수량 합계', field:'GOOD_QTY',
formatter:"money", formatterParams:{thousand:",", precision:false}
},
{headerHozAlign:'center', hozAlign:'right', minWidth:120, widthGrow:1, title:'불량수량 합계', field:'DEFECTIVE_QTY',
formatter:"money", formatterParams:{thousand:",", precision:false}
},
{headerHozAlign:'center', hozAlign:'right', minWidth:100, widthGrow:1, title:'불량율', field:'DEFECT_RATE',
formatter: function(cell, formatterParams, onRendered){
var val = fnc_checkNull(cell.getValue());
if(val === '폐기') return '<span class="status-discard">폐기</span>';
if(val === '수정') return '<span class="status-modify">수정</span>';
if(val === '특채') return '<span class="status-special">특채</span>';
return val;
return val != '' ? val + '%' : '';
}
}
},
{headerHozAlign:'center', hozAlign:'right', minWidth:120, widthGrow:1, title:'재생수량 합계', field:'REGENERATION_QTY',
formatter:"money", formatterParams:{thousand:",", precision:false}
},
{headerHozAlign:'center', hozAlign:'right', minWidth:140, widthGrow:1, title:'최종 양품수량 합계', field:'FINAL_GOOD_QTY',
formatter:"money", formatterParams:{thousand:",", precision:false}
},
{headerHozAlign:'center', hozAlign:'center', minWidth:110, widthGrow:1, title:'검사일', field:'INSPECTION_DATE',
formatter:fnc_createGridAnchorTag,
cellClick: function(e, cell){
fn_openInspectionPopUp(cell.getData());
}
},
{headerHozAlign:'center', hozAlign:'center', minWidth:100, widthGrow:1, title:'검사자', field:'WRITER_NAME'}
];
// 조회
@@ -79,20 +272,10 @@ function fn_search(){
_tabulGrid = fnc_tabul_search(_tabul_layout_fitColumns, _tabulGrid, "/quality/semiProductInspectionGridList.do", columns, true);
}
// 반제품검사 등록 팝업
function fn_registPopUp(){
var selected = _tabulGrid.getSelectedData();
if(selected.length == 0){
Swal.fire("선택된 데이터가 없습니다.");
return;
}
if(selected.length > 1){
Swal.fire("한건씩 등록 가능합니다.");
return;
}
var popup_width = 1000;
var popup_height = 600;
// 검사일 클릭 시 검사결과 확인/수정 팝업
function fn_openInspectionPopUp(rowData){
var popup_width = 1500;
var popup_height = 900;
var hiddenForm = document.hiddenForm;
var target = "semiProductInspectionPopUp";
var url = "/quality/semiProductInspectionFormPopUp.do";
@@ -100,27 +283,57 @@ function fn_registPopUp(){
fn_centerPopup(popup_width, popup_height, "", target);
hiddenForm.action = url;
hiddenForm.OBJID.value = selected[0].OBJID;
hiddenForm.OBJID.value = rowData.OBJID || '';
hiddenForm.INSPECTION_GROUP_ID.value = rowData.INSPECTION_GROUP_ID || '';
hiddenForm.MODEL_NAME.value = rowData.MODEL_NAME || '';
hiddenForm.WORK_ORDER_NO.value = rowData.WORK_ORDER_NO || '';
hiddenForm.PART_NO.value = rowData.PART_NO || '';
hiddenForm.PART_NAME.value = rowData.PART_NAME || '';
hiddenForm.INSPECTION_DATE.value = rowData.INSPECTION_DATE || '';
hiddenForm.actionType.value = 'view';
hiddenForm.target = target;
hiddenForm.submit();
}
// 엑셀 다운로드
function fn_excelDownload(){
var form = document.form1;
form.action = "/quality/semiProductInspectionExcelDownload.do";
form.submit();
form.action = "";
// 반제품검사 등록 팝업 (신규 등록)
function fn_registPopUp(){
var popup_width = 1800;
var popup_height = 1050;
var hiddenForm = document.hiddenForm;
var target = "semiProductInspectionPopUp";
var url = "/quality/semiProductInspectionFormPopUp.do";
fn_centerPopup(popup_width, popup_height, "", target);
hiddenForm.action = url;
hiddenForm.OBJID.value = ''; // 신규 등록이므로 빈값
hiddenForm.INSPECTION_GROUP_ID.value = ''; // 신규 등록이므로 빈값
hiddenForm.actionType.value = 'new';
hiddenForm.MODEL_NAME.value = '';
hiddenForm.WORK_ORDER_NO.value = '';
hiddenForm.PART_NO.value = '';
hiddenForm.PART_NAME.value = '';
hiddenForm.INSPECTION_DATE.value = '';
hiddenForm.target = target;
hiddenForm.submit();
}
</script>
<body>
<form name="hiddenForm" id="hiddenForm" method="post">
<input type="hidden" name="OBJID" id="OBJID">
<input type="hidden" name="INSPECTION_GROUP_ID" id="INSPECTION_GROUP_ID">
<input type="hidden" name="actionType" id="actionType">
<input type="hidden" name="MODEL_NAME" id="MODEL_NAME">
<input type="hidden" name="WORK_ORDER_NO" id="WORK_ORDER_NO">
<input type="hidden" name="PART_NO" id="PART_NO">
<input type="hidden" name="PART_NAME" id="PART_NAME">
<input type="hidden" name="INSPECTION_DATE" id="INSPECTION_DATE">
</form>
<form name="form1" id="form1" action="" method="post">
<input type="hidden" name="actionType" value="" />
<div class="content-box" style="height: 99.3%;">
<div class="content-box-s">
<div class="plm_menu_name_gdnsi">
@@ -130,11 +343,59 @@ function fn_excelDownload(){
<div class="btnArea">
<input type="button" class="plm_btns" value="반제품검사 등록" id="btnRegist">
<input type="button" class="plm_btns" value="조회" id="btnSearch">
<input type="button" class="plm_btns excel" value="Excel Download" id="btnExcel">
<input type="button" class="plm_btns" value="Excel Download" id="btnExcel">
</div>
</div>
<!-- 검색필터 없음 -->
<!-- 검색필터 -->
<div id="plmSearchZon">
<table>
<tr>
<td><label for="">품명(모델명)</label></td>
<td>
<select name="search_model_name" id="search_model_name" class="select2" style="width:150px;" autocomplete="off">
<option value="">전체</option>
${code_map.model_name}
</select>
</td>
<td><label for="">작업지시번호</label></td>
<td><input type="text" name="search_work_order_no" id="search_work_order_no" style="width:150px;" autocomplete="off" value="${param.search_work_order_no}"></td>
<td><label for="">부품품번</label></td>
<td>
<select name="search_part_no" id="search_part_no" class="select2" style="width:170px;" autocomplete="off">
<option value="">전체</option>
${code_map.part_no}
</select>
</td>
<td><label for="">부품명</label></td>
<td>
<select name="search_part_name" id="search_part_name" class="select2" style="width:180px;" autocomplete="off">
<option value="">전체</option>
${code_map.part_name}
</select>
</td>
<td><label for="">검사일</label></td>
<td>
<select name="search_inspection_date" id="search_inspection_date" class="select2" style="width:150px;" autocomplete="off">
<option value="">전체</option>
${code_map.inspection_date}
</select>
</td>
<td><label for="">검사자</label></td>
<td>
<select name="search_writer" id="search_writer" class="select2" style="width:150px;" autocomplete="off">
<option value="">전체</option>
${code_map.writer}
</select>
</td>
</tr>
</table>
</div>
<%@include file= "/WEB-INF/view/common/common_gridArea.jsp" %>
</div>

View File

@@ -2142,4 +2142,28 @@ public class PurchaseOrderController {
return resultMap;
}
/**
* 입고관리 데이터 드롭다운용 조회 (반제품검사 팝업에서 사용)
* @param request
* @param paramMap
* @return
*/
@ResponseBody
@RequestMapping("/purchaseOrder/getDeliveryListForDropdown.do")
public Map getDeliveryListForDropdown(HttpServletRequest request, @RequestParam Map paramMap){
Map resultMap = new HashMap();
try {
List list = purchaseOrderService.getDeliveryListForDropdown(request, paramMap);
resultMap.put("list", list);
resultMap.put("result", true);
} catch (Exception e) {
e.printStackTrace();
resultMap.put("result", false);
resultMap.put("message", e.getMessage());
}
return resultMap;
}
}

View File

@@ -611,16 +611,42 @@ public class QualityController {
*/
@RequestMapping("/quality/semiProductInspectionList.do")
public String semiProductInspectionList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
return "/quality/semiProductInspectionList";
String actionType = CommonUtils.checkNull(paramMap.get("actionType"));
System.out.println("[DEBUG] semiProductInspectionList actionType: " + actionType);
Map code_map = new HashMap();
List list = null;
try {
// 품명(모델명) 드롭박스
code_map.put("model_name", commonService.bizMakeOptionList("", (String)paramMap.get("search_model_name"), "quality.getSemiProductModelNameList"));
// 부품품번 드롭박스
code_map.put("part_no", commonService.bizMakeOptionList("", (String)paramMap.get("search_part_no"), "quality.getSemiProductPartNoList"));
// 부품명 드롭박스
code_map.put("part_name", commonService.bizMakeOptionList("", (String)paramMap.get("search_part_name"), "quality.getSemiProductPartNameList"));
// 검사일 드롭박스
code_map.put("inspection_date", commonService.bizMakeOptionList("", (String)paramMap.get("search_inspection_date"), "quality.getSemiProductInspectionDateList"));
// 검사자 드롭박스
code_map.put("writer", commonService.bizMakeOptionList("", (String)paramMap.get("search_writer"), "quality.getSemiProductWriterList"));
request.setAttribute("code_map", code_map);
// 엑셀 다운로드
if("excel".equals(actionType)){
list = commonService.selectList("quality.getSemiProductInspectionListForExcel", request, paramMap);
request.setAttribute("LIST", list);
}
} catch(Exception e) {
e.printStackTrace();
}
return "/quality/semiProductInspectionList" + ("excel".equals(actionType) ? "Excel" : "");
}
/**
* 반제품검사 관리 그리드 목록 조회
*/
@ResponseBody
@RequestMapping("/quality/semiProductInspectionGridList.do")
public String semiProductInspectionGridList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
request.setAttribute("RESULT", CommonUtils.getJsonArray(service.getSemiProductInspectionList(request, paramMap)));
return "/ajax/ajaxResult";
public Map semiProductInspectionGridList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
commonService.selectListPagingNew("quality.getSemiProductInspectionList", request, paramMap);
return paramMap;
}
/**
@@ -634,15 +660,64 @@ public class QualityController {
}
/**
* 반제품검사 엑셀 다운로드
* 반제품검사 저장
*/
@RequestMapping("/quality/saveSemiProductInspection.do")
public String saveSemiProductInspection(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map map = service.saveSemiProductInspection(request, paramMap);
request.setAttribute("RESULT", CommonUtils.getJsonMap(map));
return "/ajax/ajaxResult";
}
/**
* 반제품검사 상세 조회 (팝업용)
*/
@ResponseBody
@RequestMapping("/quality/getSemiProductInspectionDetail.do")
public Map getSemiProductInspectionDetail(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
return service.getSemiProductInspectionDetail(paramMap);
}
/**
* 반제품검사 삭제
*/
@ResponseBody
@RequestMapping("/quality/deleteSemiProductInspection.do")
public Map deleteSemiProductInspection(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
return service.deleteSemiProductInspection(paramMap);
}
/**
* 반제품검사 행 잠금 (수정 불가 처리)
*/
@ResponseBody
@RequestMapping("/quality/lockSemiProductInspection.do")
public Map lockSemiProductInspection(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
return service.lockSemiProductInspection(paramMap);
}
/**
* 반제품검사 엑셀 다운로드 (JSP 방식)
*/
@RequestMapping("/quality/semiProductInspectionExcelDownload.do")
public String semiProductInspectionExcelDownload(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
List list = service.getSemiProductInspectionList(request, paramMap);
List list = service.getSemiProductInspectionListForExcel(paramMap);
request.setAttribute("LIST", list);
return "/quality/semiProductInspectionExcel";
}
/**
* 반제품검사 엑셀 데이터 조회 (AJAX JSON)
*/
@ResponseBody
@RequestMapping("/quality/getSemiProductInspectionListForExcel.do")
public Map getSemiProductInspectionListForExcel(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map result = new HashMap();
List list = service.getSemiProductInspectionListForExcel(paramMap);
result.put("list", list);
return result;
}
// =====================================================
// 고객 CS 관리
// =====================================================
@@ -876,4 +951,23 @@ public class QualityController {
return service.saveIncomingInspectionProgress(request, paramMap);
}
/**
* OBJID 생성 (첨부파일 등록을 위한 미리 생성)
*/
@ResponseBody
@RequestMapping("/quality/generateObjId.do")
public Map generateObjId(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map result = new HashMap();
try {
String objId = CommonUtils.createObjId();
result.put("OBJID", objId);
result.put("result", true);
} catch(Exception e) {
e.printStackTrace();
result.put("result", false);
result.put("msg", e.getMessage());
}
return result;
}
}

View File

@@ -6082,4 +6082,26 @@ FROM(
WHERE OBJID = #{OBJID}
</update>
<!-- 입고관리 데이터 드롭다운용 조회 (반제품검사 팝업에서 사용) -->
<!-- ARRIVAL_PLAN 테이블에서 입고완료된 품목 조회 (1차+2차 합산) -->
<select id="getDeliveryListForDropdown" parameterType="map" resultType="map">
SELECT
AP.ORDER_PART_OBJID AS OBJID
,AP.PART_OBJID
,COALESCE(CASE WHEN POM.TYPE IN ('0001070','0001069') THEN PM.PART_NO ELSE POP.PART_NO END, PM.PART_NO, '') AS PART_NO
,COALESCE(POP.PART_NAME, PM.PART_NAME, '') AS PART_NAME
,COALESCE(POP.PART_NAME, PM.PART_NAME, '') AS MODEL_NAME
,COALESCE(POM.PURCHASE_ORDER_NO, '') AS WORK_ORDER_NO
,COALESCE(SUM(AP.RECEIPT_QTY::NUMERIC), 0) AS RECEIPT_QTY
FROM ARRIVAL_PLAN AP
LEFT JOIN PURCHASE_ORDER_PART POP ON POP.OBJID = AP.ORDER_PART_OBJID
LEFT JOIN PART_MNG PM ON PM.OBJID::VARCHAR = AP.PART_OBJID OR PM.OBJID = POP.PART_OBJID
LEFT JOIN PURCHASE_ORDER_MASTER POM ON POM.OBJID = AP.PARENT_OBJID
WHERE AP.RECEIPT_QTY IS NOT NULL
AND AP.RECEIPT_QTY::NUMERIC > 0
AND AP.INVENTORY_STATUS = 'Y'
GROUP BY AP.ORDER_PART_OBJID, AP.PART_OBJID, POP.PART_NO, POP.PART_NAME, PM.PART_NO, PM.PART_NAME, POM.PURCHASE_ORDER_NO, POM.TYPE
ORDER BY PART_NO
</select>
</mapper>

View File

@@ -1351,18 +1351,265 @@
반제품검사 관리
===================================================== -->
<!-- 반제품검사 목록 조회 -->
<!-- 반제품검사 목록 조회 (영업관리 방식: 작업지시번호 기준 그룹화, 나머지는 "외 N건") -->
<select id="getSemiProductInspectionList" parameterType="map" resultType="map">
SELECT SPI.OBJID
, SPI.PROJECT_NO
, SPI.WORK_ORDER_NO
, SPI.PART_NO
, SPI.PART_NAME
, SPI.RECEIPT_QTY
, SPI.DISPOSITION_TYPE
SELECT T.INSPECTION_GROUP_ID
, MIN(T.OBJID) AS OBJID
<!-- 작업지시번호: 여러 개면 "XXX 외 N건" (빈값/NULL 제외) -->
, (SELECT CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MAX(val)
ELSE MAX(val) || ' 외 ' || (COUNT(*) - 1) || '건'
END
FROM (SELECT DISTINCT T2.WORK_ORDER_NO AS val FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION T2
WHERE T2.INSPECTION_GROUP_ID = T.INSPECTION_GROUP_ID
AND T2.WORK_ORDER_NO IS NOT NULL AND T2.WORK_ORDER_NO != '') sub
) AS WORK_ORDER_NO
<!-- 품명(모델명): 여러 개면 "XXX 외 N건" (빈값/NULL 제외) -->
, (SELECT CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MAX(val)
ELSE MAX(val) || ' 외 ' || (COUNT(*) - 1) || '건'
END
FROM (SELECT DISTINCT T2.MODEL_NAME AS val FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION T2
WHERE T2.INSPECTION_GROUP_ID = T.INSPECTION_GROUP_ID
AND T2.MODEL_NAME IS NOT NULL AND T2.MODEL_NAME != '') sub
) AS MODEL_NAME
<!-- 부품품번: 여러 개면 "XXX 외 N건" (빈값/NULL 제외) -->
, (SELECT CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MAX(val)
ELSE MAX(val) || ' 외 ' || (COUNT(*) - 1) || '건'
END
FROM (SELECT DISTINCT T2.PART_NO AS val FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION T2
WHERE T2.INSPECTION_GROUP_ID = T.INSPECTION_GROUP_ID
AND T2.PART_NO IS NOT NULL AND T2.PART_NO != '') sub
) AS PART_NO
<!-- 부품명: 여러 개면 "XXX 외 N건" (빈값/NULL 제외) -->
, (SELECT CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MAX(val)
ELSE MAX(val) || ' 외 ' || (COUNT(*) - 1) || '건'
END
FROM (SELECT DISTINCT T2.PART_NAME AS val FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION T2
WHERE T2.INSPECTION_GROUP_ID = T.INSPECTION_GROUP_ID
AND T2.PART_NAME IS NOT NULL AND T2.PART_NAME != '') sub
) AS PART_NAME
<!-- 검사일: 여러 개면 "XXX 외 N건" (빈값/NULL 제외) -->
, (SELECT CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MAX(val)
ELSE MAX(val) || ' 외 ' || (COUNT(*) - 1) || '건'
END
FROM (SELECT DISTINCT COALESCE(TO_CHAR(T2.INSPECTION_DATE, 'YYYY-MM-DD'), TO_CHAR(T2.REG_DATE, 'YYYY-MM-DD')) AS val
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION T2
WHERE T2.INSPECTION_GROUP_ID = T.INSPECTION_GROUP_ID
AND (T2.INSPECTION_DATE IS NOT NULL OR T2.REG_DATE IS NOT NULL)) sub
) AS INSPECTION_DATE
<!-- 검사자: 여러 개면 "XXX 외 N건" (빈값/NULL 제외) -->
, (SELECT CASE
WHEN COUNT(*) = 0 THEN ''
WHEN COUNT(*) = 1 THEN MAX(val)
ELSE MAX(val) || ' 외 ' || (COUNT(*) - 1) || '건'
END
FROM (SELECT DISTINCT COALESCE((SELECT USER_NAME FROM USER_INFO WHERE USER_ID = T2.INSPECTOR),
(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = T2.WRITER)) AS val
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION T2
WHERE T2.INSPECTION_GROUP_ID = T.INSPECTION_GROUP_ID
AND (T2.INSPECTOR IS NOT NULL OR T2.WRITER IS NOT NULL)) sub
WHERE val IS NOT NULL AND val != ''
) AS WRITER_NAME
<!-- 수량 집계 -->
, SUM(T.RECEIPT_QTY) AS RECEIPT_QTY
, SUM(T.GOOD_QTY) AS GOOD_QTY
, SUM(T.DEFECT_QTY) AS DEFECTIVE_QTY
, CASE
WHEN SUM(T.RECEIPT_QTY) > 0
THEN ROUND(SUM(T.DEFECT_QTY) * 100.0 / SUM(T.RECEIPT_QTY), 2)
ELSE 0
END AS DEFECT_RATE
, SUM(CASE WHEN T.DISPOSITION_TYPE = '수정' THEN T.DEFECT_QTY ELSE 0 END) AS REGENERATION_QTY
, SUM(T.GOOD_QTY) + SUM(CASE WHEN T.DISPOSITION_TYPE = '수정' THEN T.DEFECT_QTY ELSE 0 END) AS FINAL_GOOD_QTY
FROM (
SELECT SPI.OBJID
, COALESCE(SPI.MODEL_NAME, '') AS MODEL_NAME
, COALESCE(SPI.WORK_ORDER_NO, '') AS WORK_ORDER_NO
, COALESCE(SPI.PART_NO, '') AS PART_NO
, COALESCE(SPI.PART_NAME, '') AS PART_NAME
, COALESCE(SPI.RECEIPT_QTY, 0) AS RECEIPT_QTY
, COALESCE(SPI.GOOD_QTY, 0) AS GOOD_QTY
, COALESCE(SPI.DEFECT_QTY, 0) AS DEFECT_QTY
, SPI.DISPOSITION_TYPE
, SPI.DATA_TYPE
, COALESCE(TO_CHAR(SPI.INSPECTION_DATE, 'YYYY-MM-DD'), TO_CHAR(SPI.REG_DATE, 'YYYY-MM-DD')) AS INSPECTION_DATE
, COALESCE((SELECT USER_NAME FROM USER_INFO WHERE USER_ID = SPI.INSPECTOR), (SELECT USER_NAME FROM USER_INFO WHERE USER_ID = SPI.WRITER)) AS WRITER_NAME
, COALESCE(SPI.INSPECTION_GROUP_ID, SPI.OBJID) AS INSPECTION_GROUP_ID
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION SPI
WHERE 1=1
<!-- 품명(모델명) 검색 -->
<if test="search_model_name != null and search_model_name != ''">
AND UPPER(SPI.MODEL_NAME) LIKE UPPER('%' || #{search_model_name} || '%')
</if>
<!-- 작업지시번호 검색 -->
<if test="search_work_order_no != null and search_work_order_no != ''">
AND UPPER(SPI.WORK_ORDER_NO) LIKE UPPER('%' || #{search_work_order_no} || '%')
</if>
<!-- 부품품번 검색 (LIKE 검색 - 외 N건 항목도 검색 가능) -->
<if test="search_part_no != null and search_part_no != ''">
AND UPPER(SPI.PART_NO) LIKE UPPER('%' || #{search_part_no} || '%')
</if>
<!-- 부품명 검색 (LIKE 검색 - 외 N건 항목도 검색 가능) -->
<if test="search_part_name != null and search_part_name != ''">
AND UPPER(SPI.PART_NAME) LIKE UPPER('%' || #{search_part_name} || '%')
</if>
<!-- 검사일 검색 -->
<if test="search_inspection_date != null and search_inspection_date != ''">
AND TO_CHAR(SPI.REG_DATE, 'YYYY-MM-DD') = #{search_inspection_date}
</if>
<!-- 검사자 검색 -->
<if test="search_writer != null and search_writer != ''">
AND SPI.WRITER = #{search_writer}
</if>
) T
GROUP BY T.INSPECTION_GROUP_ID
ORDER BY MIN(T.INSPECTION_DATE) DESC, T.INSPECTION_GROUP_ID
</select>
<!-- 반제품검사 엑셀 다운로드용 데이터 조회 (그룹화 후 쉼표로 나열) -->
<select id="getSemiProductInspectionListForExcel" parameterType="map" resultType="map">
SELECT T.INSPECTION_GROUP_ID
, MIN(T.OBJID) AS OBJID
<!-- 품명(모델명): 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.MODEL_NAME, ''), ', ' ORDER BY NULLIF(T.MODEL_NAME, '')) AS MODEL_NAME
<!-- 제품구분: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.PRODUCT_TYPE, ''), ', ' ORDER BY NULLIF(T.PRODUCT_TYPE, '')) AS PRODUCT_TYPE
<!-- 작업지시번호: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.WORK_ORDER_NO, ''), ', ' ORDER BY NULLIF(T.WORK_ORDER_NO, '')) AS WORK_ORDER_NO
<!-- 부품품번: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.PART_NO, ''), ', ' ORDER BY NULLIF(T.PART_NO, '')) AS PART_NO
<!-- 부품명: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.PART_NAME, ''), ', ' ORDER BY NULLIF(T.PART_NAME, '')) AS PART_NAME
<!-- 수량 집계 -->
, SUM(T.RECEIPT_QTY) AS RECEIPT_QTY
, SUM(T.GOOD_QTY) AS GOOD_QTY
, SUM(T.DEFECT_QTY) AS DEFECT_QTY
, CASE
WHEN SUM(T.RECEIPT_QTY) > 0
THEN ROUND(SUM(T.DEFECT_QTY) * 100.0 / SUM(T.RECEIPT_QTY), 2)
ELSE 0
END AS DEFECT_RATE
, SUM(CASE WHEN T.DISPOSITION_TYPE = '수정' THEN T.DEFECT_QTY ELSE 0 END) AS REGENERATION_QTY
, SUM(T.GOOD_QTY) + SUM(CASE WHEN T.DISPOSITION_TYPE = '수정' THEN T.DEFECT_QTY ELSE 0 END) AS FINAL_GOOD_QTY
<!-- 검사일: 쉼표로 나열 -->
, STRING_AGG(DISTINCT T.INSPECTION_DATE_STR, ', ' ORDER BY T.INSPECTION_DATE_STR) AS INSPECTION_DATE
<!-- 검사자: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.WRITER_NAME, ''), ', ' ORDER BY NULLIF(T.WRITER_NAME, '')) AS WRITER_NAME
<!-- 불량유형: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.DEFECT_TYPE, ''), ', ' ORDER BY NULLIF(T.DEFECT_TYPE, '')) AS DEFECT_TYPE
<!-- 불량원인: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.DEFECT_CAUSE, ''), ', ' ORDER BY NULLIF(T.DEFECT_CAUSE, '')) AS DEFECT_CAUSE
<!-- 귀책부서: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.RESPONSIBLE_DEPT, ''), ', ' ORDER BY NULLIF(T.RESPONSIBLE_DEPT, '')) AS RESPONSIBLE_DEPT
<!-- 처리현황: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.PROCESS_STATUS, ''), ', ' ORDER BY NULLIF(T.PROCESS_STATUS, '')) AS PROCESS_STATUS
<!-- 처리결과: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.DISPOSITION_TYPE, ''), ', ' ORDER BY NULLIF(T.DISPOSITION_TYPE, '')) AS DISPOSITION_TYPE
<!-- 비고: 쉼표로 나열 -->
, STRING_AGG(DISTINCT NULLIF(T.REMARK, ''), ', ' ORDER BY NULLIF(T.REMARK, '')) AS REMARK
FROM (
SELECT SPI.OBJID
, COALESCE(SPI.INSPECTION_GROUP_ID, SPI.OBJID::VARCHAR) AS INSPECTION_GROUP_ID
, COALESCE(SPI.MODEL_NAME, '') AS MODEL_NAME
, COALESCE(SPI.PRODUCT_TYPE, '') AS PRODUCT_TYPE
, COALESCE(SPI.WORK_ORDER_NO, '') AS WORK_ORDER_NO
, COALESCE(SPI.PART_NO, '') AS PART_NO
, COALESCE(SPI.PART_NAME, '') AS PART_NAME
, COALESCE(SPI.RECEIPT_QTY, 0) AS RECEIPT_QTY
, COALESCE(SPI.GOOD_QTY, 0) AS GOOD_QTY
, COALESCE(SPI.DEFECT_QTY, 0) AS DEFECT_QTY
, COALESCE(TO_CHAR(SPI.INSPECTION_DATE, 'YYYY-MM-DD'), TO_CHAR(SPI.REG_DATE, 'YYYY-MM-DD')) AS INSPECTION_DATE_STR
, COALESCE((SELECT USER_NAME FROM USER_INFO WHERE USER_ID = SPI.INSPECTOR),
(SELECT USER_NAME FROM USER_INFO WHERE USER_ID = SPI.WRITER), '') AS WRITER_NAME
, COALESCE(SPI.DEFECT_TYPE, '') AS DEFECT_TYPE
, COALESCE(SPI.DEFECT_CAUSE, '') AS DEFECT_CAUSE
, COALESCE(SPI.RESPONSIBLE_DEPT, '') AS RESPONSIBLE_DEPT
, COALESCE(SPI.PROCESS_STATUS, '') AS PROCESS_STATUS
, COALESCE(SPI.DISPOSITION_TYPE, '') AS DISPOSITION_TYPE
, COALESCE(SPI.REMARK, '') AS REMARK
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION SPI
WHERE 1=1
<!-- 품명(모델명) 검색 -->
<if test="search_model_name != null and search_model_name != ''">
AND UPPER(SPI.MODEL_NAME) LIKE UPPER('%' || #{search_model_name} || '%')
</if>
<!-- 작업지시번호 검색 -->
<if test="search_work_order_no != null and search_work_order_no != ''">
AND UPPER(SPI.WORK_ORDER_NO) LIKE UPPER('%' || #{search_work_order_no} || '%')
</if>
<!-- 부품품번 검색 -->
<if test="search_part_no != null and search_part_no != ''">
AND UPPER(SPI.PART_NO) LIKE UPPER('%' || #{search_part_no} || '%')
</if>
<!-- 부품명 검색 -->
<if test="search_part_name != null and search_part_name != ''">
AND UPPER(SPI.PART_NAME) LIKE UPPER('%' || #{search_part_name} || '%')
</if>
<!-- 검사일 검색 -->
<if test="search_inspection_date != null and search_inspection_date != ''">
AND TO_CHAR(SPI.REG_DATE, 'YYYY-MM-DD') = #{search_inspection_date}
</if>
<!-- 검사자 검색 -->
<if test="search_writer != null and search_writer != ''">
AND SPI.WRITER = #{search_writer}
</if>
) T
GROUP BY T.INSPECTION_GROUP_ID
ORDER BY MIN(T.INSPECTION_DATE_STR) DESC, T.INSPECTION_GROUP_ID
</select>
<!-- 반제품검사 품명(모델명) 드롭박스 목록 (CODE, NAME 형태) -->
<select id="getSemiProductModelNameList" parameterType="map" resultType="map">
SELECT DISTINCT MODEL_NAME AS CODE
, MODEL_NAME AS NAME
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE MODEL_NAME IS NOT NULL AND MODEL_NAME != ''
ORDER BY CODE
</select>
<!-- 반제품검사 부품품번 드롭박스 목록 (CODE, NAME 형태) -->
<select id="getSemiProductPartNoList" parameterType="map" resultType="map">
SELECT DISTINCT PART_NO AS CODE
, PART_NO AS NAME
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE PART_NO IS NOT NULL AND PART_NO != ''
ORDER BY CODE
</select>
<!-- 반제품검사 부품명 드롭박스 목록 (CODE, NAME 형태) -->
<select id="getSemiProductPartNameList" parameterType="map" resultType="map">
SELECT DISTINCT PART_NAME AS CODE
, PART_NAME AS NAME
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE PART_NAME IS NOT NULL AND PART_NAME != ''
ORDER BY CODE
</select>
<!-- 반제품검사 검사일 드롭박스 목록 (CODE, NAME 형태) -->
<select id="getSemiProductInspectionDateList" parameterType="map" resultType="map">
SELECT DISTINCT TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS CODE
, TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS NAME
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE REG_DATE IS NOT NULL
ORDER BY CODE DESC
</select>
<!-- 반제품검사 검사자 드롭박스 목록 (CODE, NAME 형태) -->
<select id="getSemiProductWriterList" parameterType="map" resultType="map">
SELECT DISTINCT SPI.WRITER AS CODE
, (SELECT USER_NAME FROM USER_INFO WHERE USER_ID = SPI.WRITER) AS NAME
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION SPI
WHERE 1=1
ORDER BY SPI.REG_DATE DESC
WHERE SPI.WRITER IS NOT NULL AND SPI.WRITER != ''
ORDER BY NAME
</select>
<!-- 반제품검사 상세 조회 -->
@@ -1377,10 +1624,215 @@
, SPI.REMARK
, SPI.WRITER
, TO_CHAR(SPI.REG_DATE, 'YYYY-MM-DD') AS REG_DATE
, SPI.INSPECTION_GROUP_ID
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION SPI
WHERE SPI.OBJID = #{OBJID}
</select>
<!-- 반제품검사 상세 조회 (타입별) -->
<select id="getSemiProductInspectionByType" parameterType="map" resultType="map">
SELECT SPI.OBJID AS "OBJID"
, SPI.OBJID AS "ROW_ID"
, COALESCE(SPI.MODEL_NAME, '') AS "MODEL_NAME"
, COALESCE(SPI.PRODUCT_TYPE, '') AS "PRODUCT_TYPE"
, COALESCE(SPI.WORK_ORDER_NO, '') AS "WORK_ORDER_NO"
, COALESCE(SPI.PART_NO, '') AS "PART_NO"
, COALESCE(SPI.PART_NAME, '') AS "PART_NAME"
, COALESCE(SPI.RECEIPT_QTY, 0) AS "RECEIPT_QTY"
, COALESCE(SPI.GOOD_QTY, 0) AS "GOOD_QTY"
, COALESCE(SPI.DEFECT_QTY, 0) AS "DEFECT_QTY"
, COALESCE(SPI.DEFECT_TYPE, '') AS "DEFECT_TYPE"
, COALESCE(SPI.DEFECT_CAUSE, '') AS "DEFECT_CAUSE"
, COALESCE(SPI.RESPONSIBLE_DEPT, '') AS "RESPONSIBLE_DEPT"
, COALESCE(SPI.PROCESS_STATUS, '') AS "PROCESS_STATUS"
, COALESCE(TO_CHAR(SPI.INSPECTION_DATE, 'YYYY-MM-DD'), '') AS "INSPECTION_DATE"
, COALESCE(SPI.INSPECTOR, '') AS "INSPECTOR"
, COALESCE(SPI.DISPOSITION_TYPE, '') AS "DISPOSITION_TYPE"
, COALESCE(SPI.REMARK, '') AS "REMARK"
, SPI.DATA_TYPE AS "DATA_TYPE"
, COALESCE(SPI.INSPECTION_GROUP_ID, '') AS "INSPECTION_GROUP_ID"
, COALESCE(SPI.IS_LOCKED, 'N') AS "IS_LOCKED"
<!-- 파일 카운트 조회 -->
, (SELECT COUNT(*) FROM ATTACH_FILE_INFO AFI WHERE AFI.TARGET_OBJID = SPI.OBJID AND AFI.DOC_TYPE = 'SEMI_INSPECTION_IMAGE' AND AFI.STATUS = 'Active') AS "IMAGE_FILE_CNT"
, (SELECT COUNT(*) FROM ATTACH_FILE_INFO AFI WHERE AFI.TARGET_OBJID = SPI.OBJID AND AFI.DOC_TYPE = 'SEMI_INSPECTION_NCR' AND AFI.STATUS = 'Active') AS "NCR_FILE_CNT"
, (SELECT COUNT(*) FROM ATTACH_FILE_INFO AFI WHERE AFI.TARGET_OBJID = SPI.OBJID AND AFI.DOC_TYPE = 'SEMI_INSPECTION_REPORT' AND AFI.STATUS = 'Active') AS "REPORT_FILE_CNT"
FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION SPI
WHERE 1=1
<if test="INSPECTION_GROUP_ID != null and INSPECTION_GROUP_ID != ''">
AND (SPI.INSPECTION_GROUP_ID = #{INSPECTION_GROUP_ID} OR SPI.OBJID = #{INSPECTION_GROUP_ID})
</if>
<if test="WORK_ORDER_NO != null and WORK_ORDER_NO != ''">
AND SPI.WORK_ORDER_NO = #{WORK_ORDER_NO}
</if>
<if test="OBJID != null and OBJID != ''">
AND SPI.OBJID = #{OBJID}
</if>
<if test="DATA_TYPE != null and DATA_TYPE != ''">
AND SPI.DATA_TYPE = #{DATA_TYPE}
</if>
ORDER BY SPI.REG_DATE
</select>
<!-- 반제품검사 저장 (INSERT) -->
<insert id="saveSemiProductInspection" parameterType="map">
INSERT INTO PMS_QUALITY_SEMI_PRODUCT_INSPECTION (
OBJID
, PROJECT_NO
, WORK_ORDER_NO
, PART_NO
, PART_NAME
, RECEIPT_QTY
, DISPOSITION_TYPE
, REMARK
, WRITER
, REG_DATE
) VALUES (
#{OBJID}
, #{PROJECT_NO}
, #{WORK_ORDER_NO}
, #{PART_NO}
, #{PART_NAME}
, #{RECEIPT_QTY}::NUMERIC
, #{DISPOSITION_TYPE}
, #{REMARK}
, #{WRITER}
, NOW()
)
</insert>
<!-- 반제품검사 수정 (UPDATE) -->
<update id="updateSemiProductInspection" parameterType="map">
UPDATE PMS_QUALITY_SEMI_PRODUCT_INSPECTION
SET PROJECT_NO = #{PROJECT_NO}
, WORK_ORDER_NO = #{WORK_ORDER_NO}
, PART_NO = #{PART_NO}
, PART_NAME = #{PART_NAME}
, RECEIPT_QTY = #{RECEIPT_QTY}::NUMERIC
, DISPOSITION_TYPE = #{DISPOSITION_TYPE}
, REMARK = #{REMARK}
, WRITER = #{WRITER}
, REG_DATE = NOW()
WHERE OBJID = #{OBJID}
</update>
<!-- 반제품검사 데이터 삭제 (그룹ID 기준) -->
<delete id="deleteSemiProductInspectionByGroupId" parameterType="map">
DELETE FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE INSPECTION_GROUP_ID = #{INSPECTION_GROUP_ID}
</delete>
<!-- 반제품검사 데이터 저장 (새 팝업 형식) -->
<insert id="insertSemiProductInspectionData" parameterType="map">
INSERT INTO PMS_QUALITY_SEMI_PRODUCT_INSPECTION (
OBJID
, MODEL_NAME
, PRODUCT_TYPE
, WORK_ORDER_NO
, PART_NO
, PART_NAME
, RECEIPT_QTY
, GOOD_QTY
, DEFECT_QTY
, DEFECT_TYPE
, DEFECT_CAUSE
, RESPONSIBLE_DEPT
, PROCESS_STATUS
, INSPECTION_DATE
, INSPECTOR
, DISPOSITION_TYPE
, REMARK
, WRITER
, REG_DATE
, DATA_TYPE
, INSPECTION_GROUP_ID
, IS_LOCKED
) VALUES (
#{OBJID}
, #{MODEL_NAME}
, #{PRODUCT_TYPE}
, #{WORK_ORDER_NO}
, #{PART_NO}
, #{PART_NAME}
, COALESCE(NULLIF(#{RECEIPT_QTY}, '')::NUMERIC, 0)
, COALESCE(NULLIF(#{GOOD_QTY}, '')::NUMERIC, 0)
, COALESCE(NULLIF(#{DEFECT_QTY}, '')::NUMERIC, 0)
, #{DEFECT_TYPE}
, #{DEFECT_CAUSE}
, #{RESPONSIBLE_DEPT}
, #{PROCESS_STATUS}
, CASE WHEN #{INSPECTION_DATE} = '' THEN NULL ELSE #{INSPECTION_DATE}::DATE END
, #{INSPECTOR}
, #{DISPOSITION_TYPE}
, #{REMARK}
, #{WRITER}
, NOW()
, #{DATA_TYPE}
, #{INSPECTION_GROUP_ID}
, COALESCE(#{IS_LOCKED}, 'N')
)
</insert>
<!-- 반제품검사 데이터 수정 (기존 OBJID 유지) -->
<update id="updateSemiProductInspectionData" parameterType="map">
UPDATE PMS_QUALITY_SEMI_PRODUCT_INSPECTION SET
MODEL_NAME = #{MODEL_NAME}
, PRODUCT_TYPE = #{PRODUCT_TYPE}
, WORK_ORDER_NO = #{WORK_ORDER_NO}
, PART_NO = #{PART_NO}
, PART_NAME = #{PART_NAME}
, RECEIPT_QTY = COALESCE(NULLIF(#{RECEIPT_QTY}, '')::NUMERIC, 0)
, GOOD_QTY = COALESCE(NULLIF(#{GOOD_QTY}, '')::NUMERIC, 0)
, DEFECT_QTY = COALESCE(NULLIF(#{DEFECT_QTY}, '')::NUMERIC, 0)
, DEFECT_TYPE = #{DEFECT_TYPE}
, DEFECT_CAUSE = #{DEFECT_CAUSE}
, RESPONSIBLE_DEPT = #{RESPONSIBLE_DEPT}
, PROCESS_STATUS = #{PROCESS_STATUS}
, INSPECTION_DATE = CASE WHEN #{INSPECTION_DATE} = '' THEN NULL ELSE #{INSPECTION_DATE}::DATE END
, INSPECTOR = #{INSPECTOR}
, DISPOSITION_TYPE = #{DISPOSITION_TYPE}
, REMARK = #{REMARK}
, IS_LOCKED = CASE WHEN IS_LOCKED = 'Y' THEN 'Y' ELSE COALESCE(#{IS_LOCKED}, 'N') END
WHERE OBJID = #{OBJID}
</update>
<!-- 반제품검사 행 잠금 (IS_LOCKED = 'Y') -->
<update id="lockSemiProductInspection" parameterType="map">
UPDATE PMS_QUALITY_SEMI_PRODUCT_INSPECTION
SET IS_LOCKED = 'Y'
WHERE OBJID = #{OBJID}
</update>
<!-- 반제품검사 데이터 삭제 (OBJID로 단건 삭제) -->
<delete id="deleteSemiProductInspectionByObjId" parameterType="map">
DELETE FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE OBJID = #{OBJID}
</delete>
<!-- 반제품검사 데이터 삭제 (특정 OBJID 제외) -->
<delete id="deleteSemiProductInspectionExcludeObjIds" parameterType="map">
DELETE FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE INSPECTION_GROUP_ID = #{INSPECTION_GROUP_ID}
<if test="EXCLUDE_OBJIDS != null and EXCLUDE_OBJIDS.size() > 0">
AND OBJID NOT IN
<foreach collection="EXCLUDE_OBJIDS" item="objId" open="(" separator="," close=")">
#{objId}
</foreach>
</if>
</delete>
<!-- 반제품검사 데이터 삭제 (타입별, 특정 OBJID 제외) -->
<delete id="deleteSemiProductInspectionByType" parameterType="map">
DELETE FROM PMS_QUALITY_SEMI_PRODUCT_INSPECTION
WHERE INSPECTION_GROUP_ID = #{INSPECTION_GROUP_ID}
AND DATA_TYPE = #{DATA_TYPE}
<if test="EXCLUDE_OBJIDS != null and EXCLUDE_OBJIDS.size() > 0">
AND OBJID NOT IN
<foreach collection="EXCLUDE_OBJIDS" item="objId" open="(" separator="," close=")">
#{objId}
</foreach>
</if>
</delete>
<!-- =====================================================
고객 CS 관리
===================================================== -->

View File

@@ -3135,6 +3135,17 @@ public class PurchaseOrderService {
return sb.toString();
}
/**
* 입고관리 데이터 드롭다운용 조회 (반제품검사 팝업에서 사용)
* @param request
* @param paramMap
* @return
* @throws Exception
*/
public List getDeliveryListForDropdown(HttpServletRequest request, Map paramMap) throws Exception {
return commonService.selectList("purchaseOrder.getDeliveryListForDropdown", request, paramMap);
}
/**
* 매입마감 처리
* PURCHASE_ORDER_MASTER의 PURCHASE_CLOSE_DATE를 현재일자로 업데이트

View File

@@ -965,6 +965,23 @@ public class QualityService extends BaseService{
return resultList;
}
/**
* 반제품검사 엑셀 다운로드용 원본 데이터 조회
*/
public List getSemiProductInspectionListForExcel(Map paramMap){
List resultList = new ArrayList();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
resultList = sqlSession.selectList("quality.getSemiProductInspectionListForExcel", paramMap);
}catch(Exception e){
e.printStackTrace();
}finally{
sqlSession.close();
}
return resultList;
}
/**
* 반제품검사 상세 조회
*/
@@ -982,6 +999,451 @@ public class QualityService extends BaseService{
return resultMap;
}
/**
* 반제품검사 상세 조회 (팝업용 - 양품/불량 데이터 분리)
*/
public Map getSemiProductInspectionDetail(Map paramMap){
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
String inspectionGroupId = CommonUtils.checkNull(paramMap.get("INSPECTION_GROUP_ID"));
String objid = CommonUtils.checkNull(paramMap.get("OBJID"));
Map searchMap = new HashMap();
// INSPECTION_GROUP_ID가 있으면 우선 사용
if(!inspectionGroupId.equals("")) {
searchMap.put("INSPECTION_GROUP_ID", inspectionGroupId);
} else if(!objid.equals("")) {
// OBJID로 해당 행의 INSPECTION_GROUP_ID 조회
Map infoMap = sqlSession.selectOne("quality.getSemiProductInspectionInfo", paramMap);
if(infoMap != null && infoMap.get("inspection_group_id") != null) {
searchMap.put("INSPECTION_GROUP_ID", CommonUtils.checkNull(infoMap.get("inspection_group_id")));
} else if(infoMap != null && infoMap.get("INSPECTION_GROUP_ID") != null) {
searchMap.put("INSPECTION_GROUP_ID", CommonUtils.checkNull(infoMap.get("INSPECTION_GROUP_ID")));
} else {
// 그룹 ID가 없으면 OBJID로 단건 조회
searchMap.put("OBJID", objid);
}
}
// 양품 데이터 (DATA_TYPE = 'GOOD')
searchMap.put("DATA_TYPE", "GOOD");
List leftData = sqlSession.selectList("quality.getSemiProductInspectionByType", searchMap);
resultMap.put("leftData", leftData);
// 불량 데이터 (DATA_TYPE = 'DEFECT')
searchMap.put("DATA_TYPE", "DEFECT");
List rightData = sqlSession.selectList("quality.getSemiProductInspectionByType", searchMap);
resultMap.put("rightData", rightData);
}catch(Exception e){
e.printStackTrace();
}finally{
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
/**
* 반제품검사 행 잠금 (IS_LOCKED = 'Y')
*/
public Map lockSemiProductInspection(Map paramMap){
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
String objIdsJson = CommonUtils.checkNull(paramMap.get("objIds"));
if(!objIdsJson.equals("") && !objIdsJson.equals("[]")){
org.json.simple.parser.JSONParser parser = new org.json.simple.parser.JSONParser();
org.json.simple.JSONArray objIdArr = (org.json.simple.JSONArray) parser.parse(objIdsJson);
for(int i = 0; i < objIdArr.size(); i++){
String objId = CommonUtils.checkNull(objIdArr.get(i));
if(!objId.equals("")){
Map lockParam = new HashMap();
lockParam.put("OBJID", objId);
sqlSession.update("quality.lockSemiProductInspection", lockParam);
}
}
}
sqlSession.commit();
resultMap.put("result", true);
resultMap.put("msg", "잠금 처리되었습니다.");
}catch(Exception e){
resultMap.put("result", false);
resultMap.put("msg", "잠금 처리에 실패했습니다.");
if(sqlSession != null) sqlSession.rollback();
e.printStackTrace();
}finally{
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
/**
* 반제품검사 삭제 (OBJID 목록으로 삭제)
*/
public Map deleteSemiProductInspection(Map paramMap){
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
String objIdsJson = CommonUtils.checkNull(paramMap.get("objIds"));
if(!objIdsJson.equals("") && !objIdsJson.equals("[]")){
org.json.simple.parser.JSONParser parser = new org.json.simple.parser.JSONParser();
org.json.simple.JSONArray objIdArr = (org.json.simple.JSONArray) parser.parse(objIdsJson);
for(int i = 0; i < objIdArr.size(); i++){
String objId = CommonUtils.checkNull(objIdArr.get(i));
if(!objId.equals("")){
Map deleteParam = new HashMap();
deleteParam.put("OBJID", objId);
sqlSession.delete("quality.deleteSemiProductInspectionByObjId", deleteParam);
}
}
}
sqlSession.commit();
resultMap.put("result", true);
resultMap.put("msg", "삭제되었습니다.");
}catch(Exception e){
resultMap.put("result", false);
resultMap.put("msg", "삭제에 실패했습니다.");
if(sqlSession != null) sqlSession.rollback();
e.printStackTrace();
}finally{
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
/**
* 반제품검사 저장 (새로운 팝업 형식)
* - 기존 INSPECTION_GROUP_ID가 있으면 수정 모드 (기존 OBJID 유지하면서 UPSERT)
* - 없으면 신규 등록 모드
*/
public Map saveSemiProductInspection(HttpServletRequest request, Map paramMap){
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
PersonBean person = (PersonBean)request.getSession().getAttribute(Constants.PERSON_BEAN);
String writer = CommonUtils.checkNull(person.getUserId());
// JSON 데이터 파싱
String leftDataStr = CommonUtils.checkNull(paramMap.get("leftData"));
String rightDataStr = CommonUtils.checkNull(paramMap.get("rightData"));
String existingGroupId = CommonUtils.checkNull(paramMap.get("INSPECTION_GROUP_ID"));
String saveType = CommonUtils.checkNull(paramMap.get("saveType"), "all"); // 저장 타입: left, right, all
String lockData = CommonUtils.checkNull(paramMap.get("lockData"), "N"); // 잠금 여부: Y, N
System.out.println("=== saveSemiProductInspection ===");
System.out.println("saveType: " + saveType);
System.out.println("lockData: " + lockData);
System.out.println("existingGroupId: " + existingGroupId);
org.json.simple.parser.JSONParser parser = new org.json.simple.parser.JSONParser();
// 검사 그룹 ID 결정 (기존 있으면 유지, 없으면 새로 생성)
String inspectionGroupId = "";
java.util.Set existingLeftObjIds = new java.util.HashSet(); // 저장할 좌측 OBJID 목록
java.util.Set existingRightObjIds = new java.util.HashSet(); // 저장할 우측 OBJID 목록
if(!existingGroupId.equals("")){
// 수정 모드: 기존 그룹 ID 유지
inspectionGroupId = existingGroupId;
} else {
// 신규 등록 모드
inspectionGroupId = CommonUtils.createObjId();
}
// 양품 정보 (leftData) 저장
if(leftDataStr != null && !leftDataStr.equals("") && !leftDataStr.equals("[]")){
org.json.simple.JSONArray leftArr = (org.json.simple.JSONArray) parser.parse(leftDataStr);
for(int i = 0; i < leftArr.size(); i++){
org.json.simple.JSONObject item = (org.json.simple.JSONObject) leftArr.get(i);
// OBJID 처리
String existingObjId = CommonUtils.checkNull(item.get("OBJID"));
String rowId = CommonUtils.checkNull(item.get("ROW_ID"));
String objId = existingObjId;
// OBJID가 비어있거나 임시 ID이면 새로 생성
if(objId.equals("") || objId.startsWith("NEW_") || objId.startsWith("EXIST_")){
objId = CommonUtils.createObjId();
}
existingLeftObjIds.add(objId); // 좌측 OBJID 목록에 추가
Map sqlParamMap = new HashMap();
sqlParamMap.put("OBJID", objId);
sqlParamMap.put("MODEL_NAME", CommonUtils.checkNull(item.get("MODEL_NAME")));
sqlParamMap.put("PRODUCT_TYPE", CommonUtils.checkNull(item.get("PRODUCT_TYPE")));
sqlParamMap.put("WORK_ORDER_NO", CommonUtils.checkNull(item.get("WORK_ORDER_NO")));
sqlParamMap.put("PART_NO", CommonUtils.checkNull(item.get("PART_NO")));
sqlParamMap.put("PART_NAME", CommonUtils.checkNull(item.get("PART_NAME")));
sqlParamMap.put("RECEIPT_QTY", CommonUtils.checkNull(item.get("RECEIPT_QTY"), "0"));
sqlParamMap.put("GOOD_QTY", CommonUtils.checkNull(item.get("GOOD_QTY"), "0"));
sqlParamMap.put("WRITER", writer);
sqlParamMap.put("DATA_TYPE", "GOOD");
sqlParamMap.put("INSPECTION_GROUP_ID", inspectionGroupId);
// 불량 정보 컬럼은 빈값으로
sqlParamMap.put("DEFECT_QTY", "0");
sqlParamMap.put("DEFECT_TYPE", "");
sqlParamMap.put("DEFECT_CAUSE", "");
sqlParamMap.put("RESPONSIBLE_DEPT", "");
sqlParamMap.put("PROCESS_STATUS", "");
sqlParamMap.put("INSPECTION_DATE", "");
sqlParamMap.put("INSPECTOR", "");
sqlParamMap.put("DISPOSITION_TYPE", "");
sqlParamMap.put("REMARK", "");
// 잠금 여부 설정
sqlParamMap.put("IS_LOCKED", lockData);
// UPSERT: UPDATE 시도 후 실패하면 INSERT
int updateCnt = sqlSession.update("quality.updateSemiProductInspectionData", sqlParamMap);
if(updateCnt == 0){
// UPDATE 실패 시 INSERT (신규 데이터)
sqlSession.insert("quality.insertSemiProductInspectionData", sqlParamMap);
}
}
}
// 양품 데이터를 ROW_ID 기준 Map으로 변환 (불량 데이터 매칭용)
Map leftDataMap = new HashMap(); // ROW_ID -> leftData 아이템
if(leftDataStr != null && !leftDataStr.equals("") && !leftDataStr.equals("[]")){
org.json.simple.JSONArray leftArrForMap = (org.json.simple.JSONArray) parser.parse(leftDataStr);
for(int i = 0; i < leftArrForMap.size(); i++){
org.json.simple.JSONObject leftItem = (org.json.simple.JSONObject) leftArrForMap.get(i);
String rowId = CommonUtils.checkNull(leftItem.get("ROW_ID"));
if(!rowId.equals("")){
leftDataMap.put(rowId, leftItem);
}
}
}
// 불량 정보 (rightData) 저장 - PARENT_ROW_ID를 기반으로 해당 양품 정보와 매칭
if(rightDataStr != null && !rightDataStr.equals("") && !rightDataStr.equals("[]")){
org.json.simple.JSONArray rightArr = (org.json.simple.JSONArray) parser.parse(rightDataStr);
for(int i = 0; i < rightArr.size(); i++){
org.json.simple.JSONObject item = (org.json.simple.JSONObject) rightArr.get(i);
// PARENT_ROW_ID로 해당 양품 정보 찾기
String parentRowId = CommonUtils.checkNull(item.get("PARENT_ROW_ID"));
org.json.simple.JSONObject parentItem = (org.json.simple.JSONObject) leftDataMap.get(parentRowId);
// 부모 양품 정보에서 값 추출
String workOrderNo = "";
String modelName = "";
String productType = "";
String partNo = "";
String partName = "";
if(parentItem != null){
// 좌측 데이터가 함께 전송된 경우 (전체 저장)
workOrderNo = CommonUtils.checkNull(parentItem.get("WORK_ORDER_NO"));
modelName = CommonUtils.checkNull(parentItem.get("MODEL_NAME"));
productType = CommonUtils.checkNull(parentItem.get("PRODUCT_TYPE"));
partNo = CommonUtils.checkNull(parentItem.get("PART_NO"));
partName = CommonUtils.checkNull(parentItem.get("PART_NAME"));
} else {
// 우측만 저장하는 경우: item에 직접 부모 정보가 포함되어 있음
workOrderNo = CommonUtils.checkNull(item.get("WORK_ORDER_NO"));
modelName = CommonUtils.checkNull(item.get("MODEL_NAME"));
productType = CommonUtils.checkNull(item.get("PRODUCT_TYPE"));
partNo = CommonUtils.checkNull(item.get("PART_NO"));
partName = CommonUtils.checkNull(item.get("PART_NAME"));
}
// OBJID 처리
String existingObjId = CommonUtils.checkNull(item.get("OBJID"));
String objId = existingObjId;
// OBJID가 비어있으면 새로 생성
if(objId.equals("") || objId.startsWith("DEFECT_") || objId.startsWith("NEW_")){
objId = CommonUtils.createObjId();
}
existingRightObjIds.add(objId); // 우측 OBJID 목록에 추가
Map sqlParamMap = new HashMap();
sqlParamMap.put("OBJID", objId);
sqlParamMap.put("DEFECT_QTY", CommonUtils.checkNull(item.get("DEFECT_QTY"), "0"));
sqlParamMap.put("DEFECT_TYPE", CommonUtils.checkNull(item.get("DEFECT_TYPE")));
sqlParamMap.put("DEFECT_CAUSE", CommonUtils.checkNull(item.get("DEFECT_CAUSE")));
sqlParamMap.put("RESPONSIBLE_DEPT", CommonUtils.checkNull(item.get("RESPONSIBLE_DEPT")));
sqlParamMap.put("PROCESS_STATUS", CommonUtils.checkNull(item.get("PROCESS_STATUS")));
sqlParamMap.put("INSPECTION_DATE", CommonUtils.checkNull(item.get("INSPECTION_DATE")));
sqlParamMap.put("INSPECTOR", CommonUtils.checkNull(item.get("INSPECTOR")));
sqlParamMap.put("DISPOSITION_TYPE", CommonUtils.checkNull(item.get("DISPOSITION_TYPE")));
sqlParamMap.put("REMARK", CommonUtils.checkNull(item.get("REMARK")));
sqlParamMap.put("WRITER", writer);
sqlParamMap.put("DATA_TYPE", "DEFECT");
sqlParamMap.put("INSPECTION_GROUP_ID", inspectionGroupId);
// 해당 양품 데이터와 연결 (부모 정보 복사)
sqlParamMap.put("WORK_ORDER_NO", workOrderNo);
sqlParamMap.put("MODEL_NAME", modelName);
sqlParamMap.put("PRODUCT_TYPE", productType);
sqlParamMap.put("PART_NO", partNo);
sqlParamMap.put("PART_NAME", partName);
sqlParamMap.put("RECEIPT_QTY", "0");
sqlParamMap.put("GOOD_QTY", "0");
// 잠금 여부 설정
sqlParamMap.put("IS_LOCKED", lockData);
// UPSERT: UPDATE 시도 후 실패하면 INSERT
int updateCnt = sqlSession.update("quality.updateSemiProductInspectionData", sqlParamMap);
if(updateCnt == 0){
// UPDATE 실패 시 INSERT (신규 데이터)
sqlSession.insert("quality.insertSemiProductInspectionData", sqlParamMap);
}
}
}
// 수정 모드일 때: 자동 삭제 비활성화 (사용자가 직접 삭제 버튼으로만 삭제)
// 데이터 손실 방지를 위해 자동 삭제 로직 제거
// 삭제는 사용자가 그리드에서 행을 선택하고 삭제 버튼을 누를 때만 수행
/*
if(!existingGroupId.equals("")){
Map deleteParam = new HashMap();
deleteParam.put("INSPECTION_GROUP_ID", inspectionGroupId);
if("left".equals(saveType)){
if(existingLeftObjIds.size() > 0){
deleteParam.put("EXCLUDE_OBJIDS", existingLeftObjIds);
deleteParam.put("DATA_TYPE", "GOOD");
sqlSession.delete("quality.deleteSemiProductInspectionByType", deleteParam);
}
} else if("right".equals(saveType)){
if(existingRightObjIds.size() > 0){
deleteParam.put("EXCLUDE_OBJIDS", existingRightObjIds);
deleteParam.put("DATA_TYPE", "DEFECT");
sqlSession.delete("quality.deleteSemiProductInspectionByType", deleteParam);
}
} else {
java.util.Set allObjIds = new java.util.HashSet();
allObjIds.addAll(existingLeftObjIds);
allObjIds.addAll(existingRightObjIds);
deleteParam.put("EXCLUDE_OBJIDS", allObjIds);
sqlSession.delete("quality.deleteSemiProductInspectionExcludeObjIds", deleteParam);
}
}
*/
sqlSession.commit();
resultMap.put("result", true);
resultMap.put("msg", "저장되었습니다.");
resultMap.put("inspectionGroupId", inspectionGroupId); // 생성된 그룹 ID 반환
}catch(Exception e){
resultMap.put("result", false);
resultMap.put("msg", "저장 중 오류가 발생했습니다: " + e.getMessage());
if(sqlSession != null) sqlSession.rollback();
e.printStackTrace();
}finally{
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
/**
* 반제품검사 품명(모델명) 드롭박스 목록
*/
public List getSemiProductModelNameList(Map paramMap){
List resultList = new ArrayList();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
resultList = sqlSession.selectList("quality.getSemiProductModelNameList", paramMap);
}catch(Exception e){
e.printStackTrace();
}finally{
sqlSession.close();
}
return resultList;
}
/**
* 반제품검사 부품품번 드롭박스 목록
*/
public List getSemiProductPartNoList(Map paramMap){
List resultList = new ArrayList();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
resultList = sqlSession.selectList("quality.getSemiProductPartNoList", paramMap);
}catch(Exception e){
e.printStackTrace();
}finally{
sqlSession.close();
}
return resultList;
}
/**
* 반제품검사 부품명 드롭박스 목록
*/
public List getSemiProductPartNameList(Map paramMap){
List resultList = new ArrayList();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
resultList = sqlSession.selectList("quality.getSemiProductPartNameList", paramMap);
}catch(Exception e){
e.printStackTrace();
}finally{
sqlSession.close();
}
return resultList;
}
/**
* 반제품검사 검사일 드롭박스 목록
*/
public List getSemiProductInspectionDateList(Map paramMap){
List resultList = new ArrayList();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
resultList = sqlSession.selectList("quality.getSemiProductInspectionDateList", paramMap);
}catch(Exception e){
e.printStackTrace();
}finally{
sqlSession.close();
}
return resultList;
}
/**
* 반제품검사 검사자 드롭박스 목록
*/
public List getSemiProductWriterList(Map paramMap){
List resultList = new ArrayList();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
resultList = sqlSession.selectList("quality.getSemiProductWriterList", paramMap);
}catch(Exception e){
e.printStackTrace();
}finally{
sqlSession.close();
}
return resultList;
}
// =====================================================
// 고객 CS 관리
// =====================================================