Files
wace_plm/WebContent/WEB-INF/view/contractMgmt/estimateRegistFormPopup.jsp
2025-10-15 18:22:21 +09:00

1302 lines
45 KiB
Plaintext

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.pms.common.utils.*"%>
<%@ page import="java.util.*"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@include file="/init_new.jsp"%>
<%
PersonBean person = (PersonBean) session.getAttribute(Constants.PERSON_BEAN);
String userId = CommonUtils.checkNull(person.getUserId());
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><%=Constants.SYSTEM_NAME%></title>
<style>
.fileListscrollTbody td {
font-size: 11px !important;
}
</style>
<script type="text/javascript">
$(function() {
//alert("${info.CATEGORY_CD}")
if("${info.CATEGORY_CD}" == '0000170' || "${info.CATEGORY_CD}" == '0000171'){//오버홀, 개조
$(".DIRECT").show();
$(".SELECT").hide();
}else{
$(".DIRECT").hide();
$(".SELECT").show();
}
if("${info.CONTRACT_RESULT}" == "0000964"){//수주
$("#category_cd,#area_cd,#target_project_no,#customer_objid,#product,#contract_result,#overhaul_order").prop("disabled","disabled");
$("#mechanical_type,#facility_qty,#target_project_no_direct").prop("readonly", true);
//$("#overhaul_order,#mechanical_type,#facility_qty,#target_project_no_direct").prop("readonly", true);
}
if ("${actionType}" == "U") {
$("#btnSave").remove();
/*
//검토내용 필수
$("#chg_user_id").attr('required', 'required');
$("#plan_date").attr('required', 'required');
$("#complete_date").attr('required', 'required');
$("#result_cd").attr('required', 'required');
$("#spec_user_id").attr('required', 'required');
$("#spec_plan_date").attr('required', 'required');
$("#spec_comp_date").attr('required', 'required');
$("#spec_result_cd").attr('required', 'required');
$("#est_user_id").attr('required', 'required');
$("#est_plan_date").attr('required', 'required');
$("#est_comp_date").attr('required', 'required');
$("#est_result_cd").attr('required', 'required');
//수주결과 필수
$("#pm_user_id").attr('required', 'required');
$("#contract_price").attr('required', 'required');
$("#project_name").attr('required', 'required');
$("#contract_del_date").attr('required', 'required');
$("#req_del_date").attr('required', 'required');
$("#contract_company").attr('required', 'required');
$("#contract_date").attr('required', 'required');
$("#manufacture_plant").attr('required', 'required');
$("#contract_result").attr('required', 'required');
*/
}
$("input:text[numberOnly]").on("keyup", function() {
$(this).val(addComma($(this).val().replace(/[^0-9]/g, "")));
});
$('.select2').select2();
//첨부파일 - 주석처리
//fnc_setFileDropZone("contractMgmt01DropZone", "${objId}", "contractMgmt01", "contractMgmt01", "fileAreaDraw",false,null,null);
//fnc_setFileDropZone("contractMgmt02DropZone", "${objId}", "contractMgmt02", "contractMgmt02", "fileAreaDraw",false,null,null);
//fnc_setFileDropZone2("contractMgmt01DropZone", "${objId}", "contractMgmt01", "contractMgmt01", "fileAreaDraw", false);
//fnc_setFileDropZone2("contractMgmt02DropZone", "${objId}", "contractMgmt02", "contractMgmt02", "fileAreaDraw", false);
//fileAreaDraw();
$("#btnUpload").click(
function() {
var files = $("#file1")[0].files;
if (files.length > 0) {
fnc_fileMultiUpload(files, null, "${objId}",
"contractMgmt01", "contractMgmt01", null,
"fileAreaDraw");
//file객체 초기화
$("#file1").val("");
} else {
Swal.fire("선택된 File이 없습니다.");
}
});
$("#btnUpload1").click(
function() {
var files = $("#file2")[0].files;
if (files.length > 0) {
fnc_fileMultiUpload(files, null, "${objId}",
"contractMgmt02", "contractMgmt02", null,
"fileAreaDraw");
//file객체 초기화
$("#file2").val("");
} else {
Swal.fire("선택된 File이 없습니다.");
}
});
//날짜
_fnc_datepick();
//저장
$("#btnSave").click(function() {
fn_save();
});
$("#btnClose").click(function() {
self.close();
});
//SR자료등록 팝업
$(".File").click(
function() {
var popup_width = 800;
var popup_height = 335;
var objId = $(this).attr("data-OBJID");
var docType = $(this).attr("data-docType");
var docTypeName = $(this).attr("data-docTypeName");
var params = "?targetObjId=" + objId + "&docType="
+ docType + "&docTypeName=" + docTypeName
+ "&callbackFnc=file_check";
var url = "/common/FileRegistPopup.do" + params;
fn_centerPopup(popup_width, popup_height, url);
});
$("#category_cd").change(function(){
if($(this).val() == '0000170' || $(this).val() == '0000171'){//오버홀, 개조
$(".DIRECT").show();
$(".SELECT").hide();
$("#target_project_no_direct").attr('required', 'required');
$("#overhaul_order").attr('required', 'required');
}else{
$(".DIRECT").hide();
$(".SELECT").show();
$("#target_project_no_direct").removeAttr('required');
$("#overhaul_order").removeAttr('required');
}
});
// S/N 관리 팝업 오픈
$("#serial_no").click(function() {
fn_openSnManagePopup();
});
// 페이지 로드 시 기존 S/N 데이터가 있으면 파싱하여 hidden 필드에 저장
var initialSnValue = $("#serial_no").val();
if(initialSnValue && initialSnValue.trim() != '') {
var snArray = initialSnValue.split(',');
var initialSnList = [];
for(var i = 0; i < snArray.length; i++) {
if(snArray[i].trim() != '') {
initialSnList.push({
id: i + 1,
value: snArray[i].trim()
});
}
}
if(initialSnList.length > 0) {
$("#serial_no_list").val(JSON.stringify(initialSnList));
snCounter = initialSnList.length + 1;
console.log("초기 S/N 데이터 로드:", initialSnList);
}
}
});
function addComma(data) {
return data.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function fnc_setFileDropZone2(divId, targetObjId, docType, docTypeName,
callbackFnc, onlyOne, preProcessor, url, okExt) {
var obj = $("#" + divId);
obj.on('dragenter', function(e) {
e.stopPropagation();
e.preventDefault();
$(".DZbgimg")
.css("background-image", "url(/images/dregndrop2.png)");
});
obj.on('dragleave', function(e) {
e.stopPropagation();
e.preventDefault();
$(".DZbgimg")
.css("background-image", "url(/images/dregndrop1.png)");
});
obj.on('dragover', function(e) {
e.stopPropagation();
e.preventDefault();
});
obj.on('drop', function(e) {
e.preventDefault();
var files = e.originalEvent.dataTransfer.files;
if (files.length < 1) {
return;
}
if (onlyOne) {
if (files.length > 1) {
Swal.fire("1개의 파일만 등록 가능합니다.");
return;
}
}
if (preProcessor != null)
eval(fnc_checkNull(preProcessor) + "();");
if (url == null)
url = "/common/fileUploadProc.do";
fnc_fileMultiUpload1(files, obj, targetObjId, docType, docTypeName,
url, callbackFnc, okExt);
//eval(uploadFnc+"(files, obj, uploadUrl, callbackFnc);");
});
}
function file_check(doctype, filesize) {
//파일 다시그리기
if (filesize > 0) {
$("#" + doctype).removeClass("file_icon file_empty_icon");
$("#" + doctype).addClass("file_icon");
} else {
$("#" + doctype).removeClass("file_icon file_empty_icon");
$("#" + doctype).addClass("file_empty_icon");
}
}
function fn_save() {
if (fnc_valitate("form1")) {
if(fn_overlapOrder()){
var message = "수정";
if ("${actionType}" == 'regist') {
message = "등록";
}
if (confirm(message + "하시겠습니까?")) {
$("#category_cd,#area_cd,#target_project_no,#customer_objid,#product,#contract_result,#overhaul_order").prop("disabled","");
// $("#facility_qty").val(
// $("#facility_qty").val().replace(/,/gi, ""));
// $("#contract_price").val(
// $("#contract_price").val().replace(/,/gi, ""));
// $("#contract_price_currency").val(
// $("#contract_price_currency").val().replace(/,/gi, ""));
// 날짜 - 제거
/* var $dateinput = $("input.date_icon");
for(var i=0; i<$dateinput.length; i++){
$dateinput.eq(i).val( $dateinput.eq(i).val().replace(/-/gi,"") );
} */
$.ajax({
url : "/contractMgmt/saveContractMgmtInfo.do",
type : "POST",
data : $("#form1").serialize(),
dataType : "json",
success : function(data) {
alert(data.msg);
opener.fn_search();
self.close();
},
error : function(jqxhr, status, error) {
}
});
}
}
}
}
function _fnc_datepick() {
var $dateinput = $("input.date_icon");
for (var i = 0; i < $dateinput.length; i++) {
$dateinput.eq(i).attr("size", "10");
$dateinput.eq(i).datepicker({
changeMonth : true,
changeYear : true
});
}
}
/* Drag & Drop 관련 함수 주석처리
function fileAreaDraw() {
fn_fileCallback("contractMgmt01", "contractMgmt01");
fn_fileCallback("contractMgmt02", "contractMgmt02");
}
//첨부파일 목록을 가져온다.
function fn_fileCallback(areaId, fileType) {
$
.ajax({
url : "/common/getFileList.do",
type : "POST",
data : {
"targetObjId" : "${objId}",
"docType" : fileType
},
dataType : "json",
async : false,
success : function(data) {
if (data.length > 0) {
//첨부파일 목록 영역 show
$("#" + areaId + "FileArea").empty();
if ($("#" + areaId + "DefaultRow").length > 0) {
$("#" + areaId + "DefaultRow").hide();
}
var appendText = "";
appendText += "<colgroup>";
appendText += " <col width='100%'>";
appendText += "</colgroup>";
$
.each(
data,
function(i) {
var _appendText = "";
var path = data[i].FILE_PATH;
var fileName = data[i].SAVED_FILE_NAME;
var fileExt = data[i].UPPER_FILE_EXT;
_appendText += "<tr>";
_appendText += " <td class='align_l' style='border:none;'><a href='javascript:fnc_downloadFile(\""
+ data[i].OBJID
+ "\")'>&nbsp;&nbsp;"
+ data[i].REAL_FILE_NAME
+ "</a>";
<c:if test="${param.actionType eq 'regist' or info.WRITER eq connectUserId or 'plm_admin' eq connectUserId}">
_appendText += " <a href='javascript:fileDelete(\""
+ data[i].OBJID
+ "\",\""
+ areaId
+ "\")'><div class='delete_btn'></div></a>";
</c:if>
_appendText += " </td>";
_appendText += "</tr>";
appendText += _appendText;
});
$("#" + areaId + "FileArea").append(appendText);
$("#" + areaId + "FileArea").show();
} else {
$("#" + areaId + "DropZone").show();
$("#" + areaId + "FileArea").empty();
$("#" + areaId + "FileArea").hide();
}
},
error : function(jqxhr, status, error) {
}
});
}
//첨부 파일 삭제
function fileDelete(fileObjId, areaId) {
var type = areaId;
if (confirm("파일을 삭제하시겠습니까?")) {
$.ajax({
url : "/common/deleteFileInfo.do",
type : "POST",
data : {
"objId" : fileObjId
},
dataType : "json",
async : true,
success : function(data) {
fileAreaDraw();
},
error : function(jqxhr, status, error) {
}
});
}
}
function fnc_fileMultiUpload1(files, obj, targetObjId, docType,
docTypeName, uploadUrl, callbackFnc, okExt) {
if (okExt != null) {
for (var i = 0; i < files.length; i++) {
var _fileName = files[i].name;
var _ext = _fileName.substring(_fileName.lastIndexOf(".") + 1)
.toUpperCase()
+ ",";
if ((okExt.toUpperCase() + ",").indexOf(_ext) < 0) {
Swal.fire("허용되지 않은 확장자입니다.\n업로드 가능 확장자 : " + okExt);
return;
}
}
} else {
var _okExt = "JSP,BAT,EXE,PHP,JS,SQL";
for (var i = 0; i < files.length; i++) {
var _fileName = files[i].name;
var _ext = _fileName.substring(_fileName.lastIndexOf(".") + 1)
.toUpperCase();
if (_okExt.toUpperCase().indexOf(_ext) > 0) {
Swal.fire("허용되지 않은 확장자입니다." + _ext);
return;
}
}
}
for (var i = 0; i < files.length; i++) {
var _fileName = files[i].name;
var pattern = /[#%&*+[]]/;
if (pattern.test(_fileName)) {
Swal.fire("파일에 허용되지 않은 특수문자를 포함하고 있습니다(#,%,&,*,+,[,]).");
return;
}
}
if (confirm(files.length + "개의 파일을 업로드 하시겠습니까?")) {
uploadUrl = fnc_checkNull(uploadUrl);
if (uploadUrl == "")
uploadUrl = "/common/fileUploadProc.do";
var data = new FormData();
for (var i = 0; i < files.length; i++) {
data.append('file', files[i]);
}
//기본정보 세팅
data.append("targetObjId", targetObjId);
data.append("docType", docType);
data.append("docTypeName", docTypeName);
//var url = "/common/fileUploadProc.do";
$.ajax({
url : uploadUrl,
method : 'post',
data : data,
dataType : 'text',
processData : false,
contentType : false,
beforeSend : function() {
_startLoading1();
},
success : function(res) {
if (fnc_checkNull(callbackFnc) != "") {
eval(callbackFnc + "();");
} else {
fnc_fileMultiUpload1_Callback(res.files);
}
},
complete : function() {
_endLoading1();
},
error : function(jqxhr, status, error) {
Swal.fire(jqxhr.statusText + ", " + status + ", "
+ error);
Swal.fire(jqxhr.status);
Swal.fire(jqxhr.responseText);
}
});
}
}
function fnc_fileMultiUpload1_Callback(files) {
for (var i = 0; i < files.length; i++)
console.log(files[i].file_nm + " - " + files[i].file_size);
}
function _startLoading1(loadingMsg) {
$(".loader_back").hide();
$(".loader").show();
}
function _endLoading1() {
$(".loader").hide();
$(".loader_back").show();
}
function fnc_numberOnly(obj) {
$("#" + obj.attr("id")).val(addComma(obj.val().replace(/[^0-9]/g, "")));
//.replace(/[^0-9]/g,""))
}
// Drag & Drop 관련 함수 주석처리 끝 */
//저장 시 중복여부를 확인한다.
function fn_overlapOrder(){
var returnFlag = false;
if ("${actionType}" == 'regist') {
var category_cd = $("#category_cd").val();
var overhaul_order = $("#overhaul_order").val();
if(overhaul_order != '' && category_cd == '0000170' || category_cd == '0000171'){//오버홀, 개조
$.ajax({
url:"/contractMgmt/overlapOrder.do",
type:"POST",
data:$("#form1").serialize(),
dataType:"json",
async:false,
success:function(data){
if(0 < data.length){
Swal.fire("대상프로젝트번호에 동일한 차수가 존재합니다.\n차수를 확인하시기 바랍니다.");
returnFlag = false;
}else{
returnFlag = true;
}
},
error: function(jqxhr, status, error){
}
});
}else{
returnFlag = true;
}
}else{
returnFlag = true;
}
return returnFlag;
}
// S/N 관리 변수 - 전역
var snList = [];
var snCounter = 1;
// S/N 목록 로드
function fn_loadSnList() {
var serialNoValue = $("#serial_no").val();
// "외 N개" 패턴 제거하고 원본 데이터 로드
var serialNoListValue = $("#serial_no_list").val();
snList = [];
if(serialNoListValue && serialNoListValue.trim() != '') {
// JSON 형태로 저장된 데이터가 있으면 파싱
try {
var loadedList = JSON.parse(serialNoListValue);
snList = loadedList;
// counter 재설정
if(snList.length > 0) {
var maxId = Math.max.apply(Math, snList.map(function(item) { return item.id; }));
snCounter = maxId + 1;
}
} catch(e) {
// JSON 파싱 실패 시 기존 로직 사용
if(serialNoValue && serialNoValue.trim() != '') {
var snArray = serialNoValue.split(',');
for(var i = 0; i < snArray.length; i++) {
if(snArray[i].trim() != '') {
snList.push({
id: snCounter++,
value: snArray[i].trim()
});
}
}
}
}
} else if(serialNoValue && serialNoValue.trim() != '') {
// hidden 필드가 없고 display 필드만 있는 경우
var snArray = serialNoValue.split(',');
for(var i = 0; i < snArray.length; i++) {
if(snArray[i].trim() != '') {
snList.push({
id: snCounter++,
value: snArray[i].trim()
});
}
}
}
fn_updateSnDisplay();
}
// S/N 관리 팝업 열기
function fn_openSnManagePopup() {
// 최신 데이터 다시 로드 (display 업데이트 없이)
var serialNoValue = $("#serial_no").val();
var serialNoListValue = $("#serial_no_list").val();
console.log("팝업 열기 시작");
console.log("serial_no_list 값:", serialNoListValue);
// 데이터가 있을 때만 로드
if(serialNoListValue && serialNoListValue.trim() != '') {
// JSON 형태로 저장된 데이터가 있으면 파싱
try {
snList = JSON.parse(serialNoListValue);
console.log("JSON 파싱 성공, snList:", snList);
// counter 재설정
if(snList.length > 0) {
var maxId = Math.max.apply(Math, snList.map(function(item) { return item.id; }));
snCounter = maxId + 1;
}
} catch(e) {
console.log("JSON 파싱 오류:", e);
snList = [];
}
} else {
console.log("저장된 데이터 없음, 빈 배열로 시작");
snList = [];
}
console.log("로드된 S/N 목록 (복사본):", JSON.parse(JSON.stringify(snList)));
console.log("snList.length:", snList.length);
// 실제 데이터 확인
if(snList.length > 0) {
console.log("첫 번째 아이템:", snList[0]);
}
// 팝업 HTML 생성
var popupHtml = '<div style="padding:10px;">';
popupHtml += ' <h3 style="margin:0 0 15px 0; text-align:center;">S/N 관리</h3>';
popupHtml += ' <div id="snListContainer" style="margin-bottom:15px; max-height:300px; overflow-y:auto;"></div>';
popupHtml += ' <div style="margin-bottom:15px; display:flex; gap:5px;">';
popupHtml += ' <input type="text" id="newSnInput" placeholder="S/N 입력" style="flex:1; padding:8px; border:1px solid #ddd; border-radius:4px;">';
popupHtml += ' <button type="button" onclick="fn_addSn()" class="plm_btns">추가</button>';
popupHtml += ' </div>';
popupHtml += ' <div style="text-align:center; margin-top:20px; display:flex; gap:10px; justify-content:center;">';
popupHtml += ' <button type="button" onclick="fn_openSequentialSnPopup()" class="plm_btns">연속번호생성</button>';
popupHtml += ' <button type="button" onclick="fn_confirmSnList()" class="plm_btns">확인</button>';
popupHtml += ' <button type="button" onclick="fn_closeSnPopup()" class="plm_btns">취소</button>';
popupHtml += ' </div>';
popupHtml += '</div>';
// 팝업 오픈 (Swal 사용)
Swal.fire({
html: popupHtml,
width: '700px',
showConfirmButton: false,
showCloseButton: true,
customClass: {
popup: 'sn-manage-popup'
},
onOpen: function() {
setTimeout(function() {
fn_renderSnList();
// 엔터키로 추가
$(".swal2-html-container #newSnInput").keypress(function(e) {
if(e.which == 13) {
fn_addSn();
return false;
}
});
}, 50);
}
});
}
// S/N 목록 렌더링
function fn_renderSnList() {
console.log("fn_renderSnList 실행, snList 길이:", snList.length);
console.log("snList 내용:", snList);
var html = '<table style="width:100%; margin-bottom:10px; border-collapse:collapse; border:1px solid #ddd;">';
html += '<colgroup><col width="15%"><col width="65%"><col width="20%"></colgroup>';
html += '<thead><tr style="background:#f5f5f5;">';
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center;">번호</th>';
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center;">S/N</th>';
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center;">삭제</th>';
html += '</tr></thead>';
html += '<tbody>';
if(snList.length == 0) {
html += '<tr><td colspan="3" style="text-align:center; padding:30px; color:#999; border:1px solid #ddd;">등록된 S/N이 없습니다.</td></tr>';
} else {
for(var i = 0; i < snList.length; i++) {
html += '<tr>';
html += '<td style="text-align:center; padding:8px; border:1px solid #ddd;">' + (i+1) + '</td>';
html += '<td style="padding:8px; border:1px solid #ddd;">' + snList[i].value + '</td>';
html += '<td style="text-align:center; padding:8px; border:1px solid #ddd;">';
html += '<button type="button" onclick="fn_deleteSn(' + snList[i].id + ')" class="plm_btns" style="padding:5px 10px; font-size:12px;">삭제</button>';
html += '</td>';
html += '</tr>';
}
}
html += '</tbody></table>';
console.log("렌더링할 HTML:", html.substring(0, 200));
// Swal 내부의 컨테이너에 렌더링
var container = $(".swal2-html-container #snListContainer");
console.log("컨테이너 찾음:", container.length);
container.html(html);
}
// S/N 추가
function fn_addSn() {
var newSn = $(".swal2-html-container #newSnInput").val().trim();
if(newSn == '') {
alert('S/N을 입력해주세요.');
return;
}
// 중복 체크
for(var i = 0; i < snList.length; i++) {
if(snList[i].value == newSn) {
alert('이미 등록된 S/N입니다.');
return;
}
}
// 추가
snList.push({
id: snCounter++,
value: newSn
});
$(".swal2-html-container #newSnInput").val('');
fn_renderSnList();
}
// S/N 삭제
function fn_deleteSn(snId) {
for(var i = 0; i < snList.length; i++) {
if(snList[i].id == snId) {
snList.splice(i, 1);
break;
}
}
fn_renderSnList();
}
// 연속번호 생성 팝업 열기
function fn_openSequentialSnPopup() {
Swal.fire({
title: '연속번호 생성',
html:
'<div style="text-align:left; padding:5px;">' +
'<div style="margin-bottom:10px;">' +
'<label style="display:block; margin-bottom:3px; font-size:13px;">시작번호 <span style="color:red;">*</span></label>' +
'<input type="text" id="seqStartNo" placeholder="예: ITEM-001" style="width:100%; padding:6px; border:1px solid #ddd; border-radius:3px; font-size:13px;">' +
'</div>' +
'<div style="margin-bottom:10px;">' +
'<label style="display:block; margin-bottom:3px; font-size:13px;">생성개수 <span style="color:red;">*</span></label>' +
'<input type="number" id="seqCount" placeholder="예: 10" min="1" max="100" style="width:100%; padding:6px; border:1px solid #ddd; border-radius:3px; font-size:13px;">' +
'</div>' +
'<div style="background:#f8f9fa; padding:8px; border-radius:3px; color:#666; font-size:11px; line-height:1.5;">' +
'예: ITEM-001, 개수 3 → ITEM-001, ITEM-002, ITEM-003<br>' +
'※ 최대 100개까지 생성 가능' +
'</div>' +
'</div>',
width: '400px',
showCancelButton: true,
confirmButtonText: '생성',
cancelButtonText: '취소',
preConfirm: () => {
const startNo = document.getElementById('seqStartNo').value.trim();
const count = parseInt(document.getElementById('seqCount').value);
if(!startNo) {
Swal.showValidationMessage('시작 번호를 입력해주세요.');
return false;
}
if(!count || count < 1) {
Swal.showValidationMessage('생성 개수를 1 이상 입력해주세요.');
return false;
}
if(count > 100) {
Swal.showValidationMessage('최대 100개까지만 생성 가능합니다.');
return false;
}
return { startNo: startNo, count: count };
}
}).then((result) => {
if(result.isConfirmed) {
fn_generateSequentialSn(result.value.startNo, result.value.count);
}
});
}
// 연속번호 생성 로직
function fn_generateSequentialSn(startNo, count) {
console.log("연속번호 생성 시작, startNo:", startNo, "count:", count);
console.log("생성 전 snList:", JSON.parse(JSON.stringify(snList)));
// 숫자 부분 추출 (마지막 연속된 숫자)
var match = startNo.match(/^(.*?)(\d+)$/);
if(!match) {
alert('올바른 형식이 아닙니다. 마지막에 숫자가 있어야 합니다. (예: ITEM-001)');
fn_openSequentialSnPopup();
return;
}
var prefix = match[1]; // 접두사 (예: "ITEM-")
var startNum = parseInt(match[2]); // 시작 숫자 (예: 1)
var numLength = match[2].length; // 숫자 자릿수 (예: 3)
console.log("prefix:", prefix, "startNum:", startNum, "numLength:", numLength);
// 연속번호 생성
var addedCount = 0;
for(var i = 0; i < count; i++) {
var currentNum = startNum + i;
var paddedNum = String(currentNum).padStart(numLength, '0');
var newSn = prefix + paddedNum;
// 중복 체크
var isDuplicate = false;
for(var j = 0; j < snList.length; j++) {
if(snList[j].value == newSn) {
isDuplicate = true;
break;
}
}
// 중복이 아니면 추가
if(!isDuplicate) {
snList.push({
id: snCounter++,
value: newSn
});
addedCount++;
console.log("추가됨:", newSn);
}
}
console.log("생성 완료, 추가된 개수:", addedCount);
console.log("생성 후 snList:", JSON.parse(JSON.stringify(snList)));
console.log("생성 후 snList.length:", snList.length);
// S/N 목록 다시 열기 - 데이터 저장 후 열기
$("#serial_no_list").val(JSON.stringify(snList));
console.log("hidden 필드에 저장:", $("#serial_no_list").val());
fn_openSnManagePopup();
}
// S/N 목록 확인 및 적용
function fn_confirmSnList() {
console.log("확인 버튼 클릭, snList:", snList);
console.log("snList.length:", snList.length);
// S/N 목록을 쉼표로 구분하여 input에 저장
var snValues = [];
for(var i = 0; i < snList.length; i++) {
snValues.push(snList[i].value);
}
// hidden 필드에 전체 목록 저장 (서버 전송용)
var jsonString = JSON.stringify(snList);
console.log("저장할 JSON:", jsonString);
$("#serial_no_list").val(jsonString);
console.log("저장 후 확인:", $("#serial_no_list").val());
fn_updateSnDisplay();
Swal.close();
}
// S/N 팝업 닫기
function fn_closeSnPopup() {
Swal.close();
}
// S/N 표시 업데이트
function fn_updateSnDisplay() {
var count = snList.length;
if(count > 0) {
// 모든 S/N을 쉼표로 연결
var snValues = [];
for(var i = 0; i < snList.length; i++) {
snValues.push(snList[i].value);
}
$("#serial_no").val(snValues.join(', '));
} else {
$("#serial_no").val('');
}
}
</script>
</head>
<body>
<form name="form1" id="form1" action="" method="post">
<input type="hidden" name="objId" id="objId" value="${objId}">
<input type="hidden" name="option" id="option">
<input type="hidden" name="actionType" id="actionType" value="${actionType}">
<input type="hidden" name="serial_no_list" id="serial_no_list" value="">
<section class="business_popup_min_width">
<div class="plm_menu_name">
<h2>
<span>영업관리_견적관리_견적요청등록</span>
</h2>
</div>
<div id="EntirePopupFormWrap">
<div class="form_popup_title">
<span>견적요청 정보입력</span>
</div>
<table class="">
<colgroup>
<col width="100%" />
</colgroup>
<tr>
<td>
<table class="pmsPopuptable">
<colgroup>
<col width="12%" />
<col width="14%" />
<col width="12%" />
<col width="14%" />
<!-- <col width="12%" />
<col width="14%" />
<col width="12%" />
<col width="10%" /> -->
</colgroup>
<!-- 첫번째 행: 주문유형(계약구분), 제품구분, 국내/해외, 고객사 -->
<tr>
<td class="input_title"><label for="">주문유형 <span style="color:red;">*</span></label></td>
<td>
<select name="category_cd" id="category_cd" required reqTitle="주문유형" type="select" class="select2">
<option value="">선택</option>
${code_map.category_cd}
</select>
</td>
<td class="input_title"><label for="">제품구분 <span style="color:red;">*</span></label></td>
<td>
<select name="product" id="product" required reqTitle="제품구분" type="select" class="select2">
<option value="">선택</option>
${code_map.product_cd}
</select>
</td>
</tr>
<tr>
<td class="input_title"><label for="">국내/해외 <span style="color:red;">*</span></label></td>
<td>
<select name="area_cd" id="area_cd" reqTitle="국내/해외" type="select" class="select2" required>
<option value="">선택</option>
${code_map.area_cd}
</select>
</td>
<td class="input_title"><label for="">고객사 <span style="color:red;">*</span></label></td>
<td>
<select name="customer_objid" id="customer_objid" required reqTitle="고객사" type="select" class="select2">
<option value="">선택</option>
${code_map.customer_cd}
</select>
</td>
</tr>
<!-- 두번째 행: 유/무상, 품번, 접수일, 품명 -->
<tr>
<td class="input_title"><label for="">유/무상 <span style="color:red;">*</span></label></td>
<td>
<select name="paid_type" id="paid_type" reqTitle="유/무상" type="select" class="select2">
<option value="">선택</option>
<option value="paid">유상</option>
<option value="free">무상</option>
</select>
</td>
<td class="input_title"><label for="">접수일 <span style="color:red;">*</span></label></td>
<td>
<input type="text" class="date_icon" name="receipt_date" id="receipt_date" reqTitle="접수일" value="${info.RECEIPT_DATE}" required>
</td>
</tr>
<tr>
<td class="input_title"><label for="">품번 <span style="color:red;">*</span></label></td>
<td>
<input type="text" name="part_no" id="part_no" required reqTitle="품번" value="${info.PART_NO}" />
</td>
<td class="input_title"><label for="">품명 <span style="color:red;">*</span></label></td>
<td>
<input type="text" name="part_name" id="part_name" required reqTitle="품명" value="${info.PART_NAME}" />
</td>
</tr>
<!-- 세번째 행: S/N(클릭하여 추가), 수량 -->
<tr>
<td class="input_title"><label for="">S/N</label></td>
<td colspan="">
<input type="text" name="serial_no" id="serial_no" placeholder="클릭하여 S/N 추가" reqTitle="S/N" value="${info.SERIAL_NO}" readonly style="cursor:pointer; background-color:#f8f9fa;" />
</td>
<td class="input_title"><label for="">수량 <span style="color:red;">*</span></label></td>
<td>
<input type="text" name="quantity" id="quantity" required reqTitle="수량" value="${info.QUANTITY}" numberOnly />
</td>
</tr>
<!-- 네번째 행: 요청날짜 -->
<tr>
<td class="input_title"><label for="">요청납기</label></td>
<td colspan="3">
<input type="text" class="date_icon" name="due_date" id="due_date" reqTitle="요청납기" value="${info.DUE_DATE}" style="">
</td>
</tr>
<!-- 다섯번째 행: 고객사요청사항 (넓은 textarea) -->
<tr>
<td class="input_title"><label for="">고객사요청사항</label></td>
<td colspan="3">
<textarea name="customer_request" id="customer_request" rows="4" style="width: 98.5%; resize: vertical;">${info.CUSTOMER_REQUEST}</textarea>
</td>
</tr>
<!-- 여섯번째 행: 환종(통화), 환율 -->
<tr>
<td class="input_title"><label for="">환종</label></td>
<td colspan="">
<select name="contract_currency" id="contract_currency" reqTitle="환종" type="select" class="select2">
<option value="">선택</option>
${code_map.contract_currency}
</select>
</td>
<td class="input_title"><label for="">환율</label></td>
<td>
<input type="text" name="exchange_rate" id="exchange_rate" reqTitle="환율" value="${info.EXCHANGE_RATE}" />
</td>
</tr>
<!-- 이전 필드들 (주석처리되어 보존) -->
<%--
<tr>
<td class="input_title"><label for="">대상프로젝트번호</label></td>
<td colspan="2" class="SELECT">
<select name="target_project_no" id="target_project_no" reqTitle="대상프로젝트번호" type="select" class="select2 SELECT">
<option value="">선택</option> ${code_map.project_no}
</select>
</td>
<td colspan="2" class="DIRECT">
<input type="text" name="target_project_no_direct" id="target_project_no_direct" class="DIRECT" reqTitle="대상프로젝트번호" value="${info.TARGET_PROJECT_NO_DIRECT}" style="display:none">
</td>
<td class="input_title"><label for="">차수</label></td>
<td colspan="2">
<input type="number" name="overhaul_order" id="overhaul_order" reqTitle="오버홀차수" value="${info.OVERHAUL_ORDER}" />
</td>
</tr>
<tr>
<td class="input_title"><label for="">타사제작번호</label></td>
<td colspan="2">
<input type="text" name="customer_production_no" id="customer_production_no" reqTitle="타사제작번호" value="${info.CUSTOMER_PRODUCTION_NO}" />
</td>
<td class="input_title"><label for="">기계형식</label></td>
<td colspan="2"><input type="text" name="mechanical_type" id="mechanical_type"
required reqTitle="기계형식" value="${info.MECHANICAL_TYPE}" /></td>
</tr>
<tr>
<td class="input_title"><label for="">예상납기일</label></td>
<td class="input_sub_title" colspan="2">
<input type="text" class="date_icon" name="due_date" id="due_date" reqTitle="예상납기일" value="${info.DUE_DATE}" required>
</td>
<td class="input_title"><label for="">고객사 프로젝트명</label></td>
<td colspan="2">
<input type="text" name="customer_project_name" id="customer_project_name" value="${info.CUSTOMER_PROJECT_NAME}" required
reqTitle="고객사 프로젝트명">
</td>
</tr>
<tr>
<td class="input_title"><label for="">입고지</label></td>
<td colspan="2"><input type="text" name="location"
id="location" required reqTitle="입고지" value="${info.LOCATION}" />
</td>
<td class="input_title"><label for="">셋업지</label></td>
<td colspan="2"><input type="text" name="setup" id="setup"
required reqTitle="셋업지" value="${info.SETUP}" /></td>
</tr>
<tr>
<td class="input_title"><label for="">설비방향</label></td>
<td colspan="2"><select name="facility" id="facility"
required reqTitle="설비방향" type="select" class="select2">
<option value="">선택</option>${code_map.facility}
</select></td>
<td class="input_title"><label for="">설비대수</label></td>
<td class="input_sub_title" colspan="2"><input type="text"
name="facility_qty" id="facility_qty" required reqTitle="설비대수" maxlength="2"
value="${info.FACILITY_QTY}" numberOnly /></td>
</tr>
<tr>
<td class="input_title"><label for="">설비타입</label></td>
<td colspan="2"><input type="text" name="facility_type"
id="facility_type" required reqTitle="설비타입"
value="${info.FACILITY_TYPE}" /></td>
<td class="input_title"><label for="">설비길이(m)</label></td>
<td class="input_sub_title" colspan="2"><input type="text"
name="facility_depth" id="facility_depth" required
reqTitle="설비길이" value="${info.FACILITY_DEPTH}" /></td>
</tr>
<tr>
<td class="input_title"><label for="">수주결과</label></td>
<td class="input_sub_title" colspan="2"><select
name="contract_result" id="contract_result" reqTitle="수주결과"
type="select" class="select2">
<option value="">선택</option>${code_map.contract_result}
</select></td>
<td class="input_title"><label for="">수주일</label></td>
<td colspan="2"><input type="text" class="date_icon"
name="contract_date" id="contract_date" reqTitle="수주일"
value="${info.CONTRACT_DATE}" /></td>
</tr>
<tr>
<td class="input_title"><label for="">PO No.</label></td>
<td class="input_sub_title" colspan="2"><input type="text"
name="po_no" id="po_no" reqTitle="po_no" value="${info.PO_NO}" />
</td>
<td class="input_title"><label for="">PM</label></td>
<td class="input_sub_title" colspan="2"><select
name="pm_user_id" id="pm_user_id" reqTitle="PM" type="select"
class="select2">
<option value="">선택</option>${code_map.pm_user_id}
</select></td>
</tr>
<tr>
<td class="input_title"><label for="">통화</label></td>
<td class="input_sub_title" colspan="2"><select
name="contract_currency" id="contract_currency" reqTitle="통화"
type="select" class="select2">
<option value="">선택</option>${code_map.contract_currency}
</select></td>
<td class="input_title"><label for="">수주가</label></td>
<td class="input_sub_title" colspan="2"><input type="text"
name="contract_price_currency" id="contract_price_currency"
value="<fmt:formatNumber value="${info.CONTRACT_PRICE_CURRENCY}" pattern="#,###" />"
reqTitle="수주가(통화)" numberOnly /></td>
</tr>
<tr>
<td class="input_title"><label for="">원화 환산금액</label></td>
<td class="input_sub_title" colspan="2"><input type="text"
name="contract_price" id="contract_price"
value="<fmt:formatNumber value="${info.CONTRACT_PRICE}" pattern="#,###" />"
reqTitle="원화 환산금액" numberOnly /></td>
<td class="input_title"><label for=""></label></td>
<td class="input_sub_title" colspan="2"></td>
</tr>
<tr>
<td class="input_title"><label for="">당사 프로젝트명</label></td>
<td class="input_sub_title" colspan="5"><input type="text"
name="project_name" id="project_name" reqTitle="당사프로젝트명"
value="${info.PROJECT_NAME}" /></td>
</tr>
<tr>
<td class="input_title"><label for="">계약납기</label></td>
<td class="input_sub_title" colspan="2"><input type="text"
class="date_icon" name="contract_del_date"
id="contract_del_date" reqTitle="계약납기"
value="${info.CONTRACT_DEL_DATE}" /></td>
<td class="input_title"><label for="">요청납기</label></td>
<td class="input_sub_title" colspan="2"><input type="text"
class="date_icon" name="req_del_date" id="req_del_date"
reqTitle="요청납기" value="${info.REQ_DEL_DATE}" /></td>
</tr>
<tr>
<td class="input_title"><label for="">수주회사</label></td>
<td class="input_sub_title" colspan="2"><select
name="contract_company" id="contract_company" reqTitle="수주회사"
type="select" class="select2">
<option value="">선택</option>${code_map.contract_company}
</select></td>
<td class="input_title"><label for="">제작공장</label></td>
<td class="input_sub_title" colspan="2"><select
name="manufacture_plant" id="manufacture_plant"
reqTitle="제작공장" type="select" class="select2">
<option value="">선택</option>${code_map.manufacture_plant}
</select></td>
</tr>
--%>
</table>
</td>
</tr>
<!-- Drag & Drop 영역 주석처리 -->
<%--
<tr>
<td style="vertical-align:top; padding-top:13px;">
<table class="pmsPopuptable" style="height:400px;">
<colgroup>
<col width="18%"/>
<col width="18%"/>
<col width="18%"/>
<col width="18%"/>
<col width="*"/>
</colgroup>
<tr style=" ">
<td colspan="3" style="vertical-align: top;">
<div class="dropzonebox">
<div id="contractMgmt01DropZone" class="new_dropzone"
style="width: 63%;" required>
<div class="DZbgimg"></div>
DRAG & DROP
</div>
<div class="new_dropzone_sc" style="width: 32%;">
<div class="loader_back"></div>
<div class="loader"></div>
</div>
<div class="dropzoneDB" style="left: 75%;">
<label>${info.FILE_SIZE1}B</label>
</div>
<div class="dropzonefile" style="left: 85%;">
<label>${info.FILE_CNT1}File</label>
</div>
</div>
</td>
<td colspan="2" style="vertical-align: top;">
<table id="contractMgmt01FileAreaTable"
class="fileListscrollThead_x"
style="width: 100% !important; border-spacing: 0;">
</table>
<div class="PmsPopuptable_scroll_hover">
<div class="PmsPopuptable_scroll_PC"
style="width: 99%; height: 160px; overflow-y: scroll;">
<table class="fileListscrollTbody" style="width: 100% !important;">
<colgroup>
<col width="100%">
</colgroup>
<tbody id="contractMgmt01FileArea" class="fileListscrollTbody">
<tr>
<td></td>
</tr>
</tbody>
</table>
<div class="cover-bar" style="right: -1.1%;"></div>
</div>
</div>
</td>
</tr>
<tr></tr>
<tr>
<td colspan="3" style="vertical-align: top;">
<div class="dropzonebox">
<div id="contractMgmt02DropZone" class="new_dropzone" style="width: 63%;" required>
<div class="DZbgimg"></div>
DRAG & DROP
</div>
<div class="new_dropzone_sc" style="width: 32%;">
<div class="loader_back"></div>
<div class="loader"></div>
</div>
<div class="dropzoneDB" style="left: 75%;">
<label>${info.FILE_SIZE2}B</label>
</div>
<div class="dropzonefile" style="left: 85%;">
<label>${info.FILE_CNT2}File</label>
</div>
</div>
</td>
<td colspan="2" style="vertical-align: top;">
<table id="contractMgmt02FileAreaTable"
class="fileListscrollThead_x"
style="width: 100% !important; border-spacing: 0;">
</table>
<div class="PmsPopuptable_scroll_hover">
<div class="PmsPopuptable_scroll_PC"
style="width: 99%; height: 160px; overflow-y: scroll;">
<table class="fileListscrollTbody"
style="width: 100% !important;">
<colgroup>
<col width="100%">
</colgroup>
<tbody id="contractMgmt02FileArea"
class="fileListscrollTbody">
<tr>
<td></td>
</tr>
</tbody>
</table>
<div class="cover-bar" style="right: -1.1%;"></div>
</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
--%>
</table>
</div>
<div class="btn_wrap">
<div class="plm_btn_wrap_center">
<c:choose>
<c:when test="${actionType eq 'view'}">
<%-- 조회 모드: 닫기 버튼만 표시 --%>
</c:when>
<c:when test="${actionType eq 'regist'}">
<input type="button" value="저장" id="btnSave" class="plm_btns">
</c:when>
<c:otherwise>
<input type="button" value="수정" id="btnSave" class="plm_btns">
</c:otherwise>
</c:choose>
<input type="button" value="닫기" id="btnClose" class="plm_btns">
</div>
</div>
</section>
</form>
</body>
</html>