엑셀까지 일단 해놓음

This commit is contained in:
leeheejin
2025-12-16 16:53:47 +09:00
parent c19b3b5738
commit 671fa173de
7 changed files with 441 additions and 139 deletions

View File

@@ -1340,61 +1340,96 @@
ORDER BY MIN(T.INSPECTION_DATE) DESC, T.INSPECTION_GROUP_ID
</select>
<!-- 반제품검사 엑셀 다운로드용 원본 데이터 조회 (그룹화 없이 모든 데이터) -->
<!-- 반제품검사 엑셀 다운로드용 데이터 조회 (그룹화 후 쉼표로 나열) -->
<select id="getSemiProductInspectionListForExcel" parameterType="map" resultType="map">
SELECT SPI.OBJID
, 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
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 SPI.RECEIPT_QTY > 0
THEN ROUND(COALESCE(SPI.DEFECT_QTY, 0) * 100.0 / SPI.RECEIPT_QTY, 2)
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
, CASE WHEN SPI.DISPOSITION_TYPE = '수정' THEN COALESCE(SPI.DEFECT_QTY, 0) ELSE 0 END AS REGENERATION_QTY
, COALESCE(SPI.GOOD_QTY, 0) + CASE WHEN SPI.DISPOSITION_TYPE = '수정' THEN COALESCE(SPI.DEFECT_QTY, 0) ELSE 0 END AS FINAL_GOOD_QTY
, 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
, SPI.DEFECT_TYPE
, SPI.DEFECT_CAUSE
, SPI.RESPONSIBLE_DEPT
, SPI.PROCESS_STATUS
, SPI.DISPOSITION_TYPE
, SPI.REMARK
, SPI.DATA_TYPE
, SPI.WRITER
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 검색) -->
<if test="search_part_no != null and search_part_no != ''">
AND UPPER(SPI.PART_NO) LIKE UPPER('%' || #{search_part_no} || '%')
</if>
<!-- 부품명 검색 (LIKE 검색) -->
<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>
ORDER BY SPI.REG_DATE DESC, MODEL_NAME, SPI.WORK_ORDER_NO, SPI.PART_NO
, 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 형태) -->

View File

@@ -76,11 +76,6 @@ $(document).ready(function(){
fn_registPopUp();
});
// 엑셀 다운로드
$("#btnExcel").click(function(){
fn_excelDownload();
});
fn_search();
});
@@ -204,13 +199,6 @@ function fn_formPopUp(objId){
hiddenForm.submit();
}
// 엑셀 다운로드
function fn_excelDownload(){
var form = document.form1;
form.action = "/quality/incomingInspectionExcelDownload.do";
form.submit();
form.action = "";
}
</script>
<body>
@@ -231,7 +219,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

@@ -79,11 +79,6 @@ $(document).ready(function(){
fn_registPopUp();
});
// 엑셀 다운로드
$("#btnExcel").click(function(){
fn_excelDownload();
});
fn_search();
});
@@ -147,13 +142,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>
@@ -172,7 +160,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

@@ -76,7 +76,7 @@ $(document).ready(function(){
fn_registPopUp();
});
// 엑셀 다운로드
// 엑셀 다운로드 (원본 데이터)
$("#btnExcel").click(function(){
fn_excelDownload();
});
@@ -84,6 +84,153 @@ $(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:'left', minWidth:150, widthGrow:2, title:'품명(모델명)', field:'MODEL_NAME'},
@@ -171,13 +318,6 @@ function fn_registPopUp(){
hiddenForm.submit();
}
// 엑셀 다운로드
function fn_excelDownload(){
var form = document.form1;
form.action = "/quality/semiProductInspectionExcelDownload.do";
form.submit();
form.action = "";
}
</script>
<body>
@@ -193,6 +333,7 @@ function fn_excelDownload(){
</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">
@@ -202,7 +343,7 @@ 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>

View File

@@ -469,7 +469,10 @@ public class QualityController {
*/
@RequestMapping("/quality/semiProductInspectionList.do")
public String semiProductInspectionList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
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"));
@@ -482,10 +485,16 @@ public class QualityController {
// 검사자 드롭박스
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";
return "/quality/semiProductInspectionList" + ("excel".equals(actionType) ? "Excel" : "");
}
/**
@@ -528,7 +537,7 @@ public class QualityController {
}
/**
* 반제품검사 엑셀 다운로드
* 반제품검사 엑셀 다운로드 (JSP 방식)
*/
@RequestMapping("/quality/semiProductInspectionExcelDownload.do")
public String semiProductInspectionExcelDownload(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
@@ -537,6 +546,18 @@ public class QualityController {
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 관리
// =====================================================

View File

@@ -1340,61 +1340,96 @@
ORDER BY MIN(T.INSPECTION_DATE) DESC, T.INSPECTION_GROUP_ID
</select>
<!-- 반제품검사 엑셀 다운로드용 원본 데이터 조회 (그룹화 없이 모든 데이터) -->
<!-- 반제품검사 엑셀 다운로드용 데이터 조회 (그룹화 후 쉼표로 나열) -->
<select id="getSemiProductInspectionListForExcel" parameterType="map" resultType="map">
SELECT SPI.OBJID
, 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
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 SPI.RECEIPT_QTY > 0
THEN ROUND(COALESCE(SPI.DEFECT_QTY, 0) * 100.0 / SPI.RECEIPT_QTY, 2)
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
, CASE WHEN SPI.DISPOSITION_TYPE = '수정' THEN COALESCE(SPI.DEFECT_QTY, 0) ELSE 0 END AS REGENERATION_QTY
, COALESCE(SPI.GOOD_QTY, 0) + CASE WHEN SPI.DISPOSITION_TYPE = '수정' THEN COALESCE(SPI.DEFECT_QTY, 0) ELSE 0 END AS FINAL_GOOD_QTY
, 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
, SPI.DEFECT_TYPE
, SPI.DEFECT_CAUSE
, SPI.RESPONSIBLE_DEPT
, SPI.PROCESS_STATUS
, SPI.DISPOSITION_TYPE
, SPI.REMARK
, SPI.DATA_TYPE
, SPI.WRITER
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 검색) -->
<if test="search_part_no != null and search_part_no != ''">
AND UPPER(SPI.PART_NO) LIKE UPPER('%' || #{search_part_no} || '%')
</if>
<!-- 부품명 검색 (LIKE 검색) -->
<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>
ORDER BY SPI.REG_DATE DESC, MODEL_NAME, SPI.WORK_ORDER_NO, SPI.PART_NO
, 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 형태) -->