2335 lines
81 KiB
Plaintext
2335 lines
81 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;
|
|
}
|
|
|
|
/* S/N 입력 필드 placeholder 색상 */
|
|
#serial_no::placeholder {
|
|
color: #999 !important;
|
|
opacity: 1;
|
|
}
|
|
|
|
#serial_no::-webkit-input-placeholder {
|
|
color: #999 !important;
|
|
}
|
|
|
|
#serial_no::-moz-placeholder {
|
|
color: #999 !important;
|
|
opacity: 1;
|
|
}
|
|
|
|
#serial_no:-ms-input-placeholder {
|
|
color: #999 !important;
|
|
}
|
|
</style>
|
|
<script type="text/javascript">
|
|
// 품목 관리 변수
|
|
var itemCounter = 1;
|
|
var itemList = [];
|
|
|
|
// 반납사유 공통코드 옵션 (숨겨진 div에서 읽어옴)
|
|
var returnReasonOptions = '';
|
|
|
|
// 품번 데이터는 AJAX로 검색하므로 초기 데이터 없음
|
|
|
|
// 프로젝트 존재 여부 체크 변수
|
|
var hasProject = false;
|
|
|
|
$(function() {
|
|
// 반납사유 옵션을 템플릿에서 읽어옴
|
|
returnReasonOptions = $('#return_reason_template').html();
|
|
|
|
//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);
|
|
// }
|
|
|
|
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();
|
|
|
|
// 품목 추가 버튼
|
|
$("#btnAddItem").click(function() {
|
|
fn_addItemRow();
|
|
});
|
|
|
|
// 프로젝트 존재 여부 먼저 확인 (동기 방식)
|
|
fn_checkProjectExists();
|
|
|
|
// 기존 품목 데이터 로드
|
|
fn_loadExistingItems();
|
|
|
|
//첨부파일 - 주석처리
|
|
//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_validateItems()) {
|
|
return false;
|
|
}
|
|
|
|
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","");
|
|
|
|
// 저장 직전 S/N 확인
|
|
console.log("=== 저장 시작 ===");
|
|
$(".item-row").each(function(index) {
|
|
var itemId = $(this).attr("id");
|
|
var snListValue = $("#" + itemId + "_sn_list").val();
|
|
console.log("품목 " + (index+1) + " (" + itemId + ") S/N:", snListValue);
|
|
});
|
|
|
|
// 품목 데이터 수집
|
|
var itemsData = fn_collectItemsData();
|
|
console.log("최종 전송 데이터:", JSON.stringify(itemsData, null, 2));
|
|
|
|
// 환율에서 콤마 제거
|
|
var exchangeRate = $("#exchange_rate").val();
|
|
if(exchangeRate) {
|
|
$("#exchange_rate").val(exchangeRate.replace(/,/g, ''));
|
|
}
|
|
|
|
// 기본 폼 데이터
|
|
var formData = $("#form1").serialize();
|
|
|
|
// 품목 데이터를 JSON 문자열로 추가
|
|
formData += "&items_json=" + encodeURIComponent(JSON.stringify(itemsData));
|
|
|
|
$.ajax({
|
|
url : "/contractMgmt/saveContractMgmtInfo.do",
|
|
type : "POST",
|
|
data : formData,
|
|
dataType : "json",
|
|
success : function(data) {
|
|
alert(data.msg);
|
|
opener.fn_search();
|
|
self.close();
|
|
},
|
|
error : function(jqxhr, status, error) {
|
|
alert("저장 중 오류가 발생했습니다.");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 품목 유효성 검사
|
|
function fn_validateItems() {
|
|
var itemRows = $(".item-row");
|
|
|
|
if(itemRows.length == 0) {
|
|
alert("최소 1개 이상의 품목을 등록해주세요.");
|
|
return false;
|
|
}
|
|
|
|
for(var i = 0; i < itemRows.length; i++) {
|
|
var $row = $(itemRows[i]);
|
|
var partObjId = $row.find(".item-part-objid").val(); // hidden 필드에서 가져오기
|
|
var quantity = $row.find(".item-quantity").val().replace(/,/g, "").trim();
|
|
|
|
if(!partObjId || partObjId == "") {
|
|
alert((i+1) + "번째 품목의 품번을 선택해주세요.");
|
|
$row.find(".item-part-no-select").focus();
|
|
return false;
|
|
}
|
|
|
|
if(quantity == "" || quantity == "0") {
|
|
alert((i+1) + "번째 품목의 수량을 입력해주세요.");
|
|
$row.find(".item-quantity").focus();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 품목 데이터 수집
|
|
function fn_collectItemsData() {
|
|
var items = [];
|
|
var itemRows = $(".item-row");
|
|
|
|
itemRows.each(function(index) {
|
|
var $row = $(this);
|
|
var itemId = $row.attr("id");
|
|
|
|
// S/N 목록 가져오기
|
|
var snListStr = $("#" + itemId + "_sn_list").val();
|
|
var snList = [];
|
|
if(snListStr && snListStr.trim() != "") {
|
|
try {
|
|
snList = JSON.parse(snListStr);
|
|
} catch(e) {
|
|
console.error("품목 " + (index+1) + " S/N 파싱 실패:", e);
|
|
snList = [];
|
|
}
|
|
}
|
|
|
|
var item = {
|
|
objId: $row.find(".item-objid").val(), // 기존 품목 OBJID (수정 시 유지)
|
|
partObjId: $row.find(".item-part-objid").val(),
|
|
partNo: $row.find(".item-part-no").val() ? $row.find(".item-part-no").val().trim() : "",
|
|
partName: $row.find(".item-part-name").val() ? $row.find(".item-part-name").val().trim() : "",
|
|
quantity: $row.find(".item-quantity").val().replace(/,/g, "").trim(),
|
|
dueDate: $row.find(".item-due-date").val().trim(),
|
|
customerRequest: $row.find(".item-customer-request").val().trim(),
|
|
returnReason: $row.find(".item-return-reason").val().trim(),
|
|
snList: snList
|
|
};
|
|
|
|
items.push(item);
|
|
});
|
|
|
|
return items;
|
|
}
|
|
|
|
// 기존 품목 데이터 로드
|
|
function fn_loadExistingItems() {
|
|
<%
|
|
@SuppressWarnings("unchecked")
|
|
List<Map<String, Object>> itemList = (List<Map<String, Object>>) request.getAttribute("itemList");
|
|
if(itemList != null && itemList.size() > 0) {
|
|
for(int i = 0; i < itemList.size(); i++) {
|
|
Map<String, Object> item = itemList.get(i);
|
|
|
|
// S/N 목록 가져오기
|
|
@SuppressWarnings("unchecked")
|
|
List<Map<String, Object>> snList = (List<Map<String, Object>>) item.get("SN_LIST");
|
|
|
|
String snListJson = "[]";
|
|
if(snList != null && snList.size() > 0) {
|
|
StringBuilder sb = new StringBuilder("[");
|
|
for(int j = 0; j < snList.size(); j++) {
|
|
Map<String, Object> sn = snList.get(j);
|
|
|
|
// SEQ와 SERIAL_NO를 대소문자 모두 시도
|
|
Object seqObj = sn.get("SEQ");
|
|
if(seqObj == null) seqObj = sn.get("seq");
|
|
if(seqObj == null) seqObj = sn.get("Seq");
|
|
|
|
Object serialNoObj = sn.get("SERIAL_NO");
|
|
if(serialNoObj == null) serialNoObj = sn.get("serial_no");
|
|
if(serialNoObj == null) serialNoObj = sn.get("serialNo");
|
|
if(serialNoObj == null) serialNoObj = sn.get("SERIALNO");
|
|
|
|
if(j > 0) sb.append(",");
|
|
sb.append("{");
|
|
sb.append("\"id\":").append(seqObj != null ? seqObj : "null").append(",");
|
|
sb.append("\"value\":\"").append(CommonUtils.checkNull(serialNoObj != null ? serialNoObj.toString() : "")).append("\"");
|
|
sb.append("}");
|
|
}
|
|
sb.append("]");
|
|
snListJson = sb.toString();
|
|
}
|
|
%>
|
|
// 품목 행 추가 - 품목 <%= i %>
|
|
(function() {
|
|
var itemId = 'item_' + itemCounter++;
|
|
// 대소문자 모두 시도
|
|
var savedItemObjId = "<%= item.get("OBJID") != null ? item.get("OBJID") : (item.get("objid") != null ? item.get("objid") : "") %>";
|
|
var savedPartObjId = "<%= item.get("PART_OBJID") != null ? item.get("PART_OBJID") : (item.get("part_objid") != null ? item.get("part_objid") : "") %>";
|
|
var savedPartNo = "<%= item.get("PART_NO") != null ? item.get("PART_NO") : (item.get("part_no") != null ? item.get("part_no") : "") %>";
|
|
var savedPartName = "<%= item.get("PART_NAME") != null ? item.get("PART_NAME") : (item.get("part_name") != null ? item.get("part_name") : "") %>";
|
|
// JSON 데이터를 안전하게 전달
|
|
var snJsonData = <%= snListJson %>;
|
|
|
|
$("#noItemRow").hide();
|
|
|
|
var html = '<tr id="' + itemId + '" class="item-row">';
|
|
html += '<td style="text-align:center; padding:5px; border:1px solid #ddd;">' + (itemCounter-1) + '</td>';
|
|
|
|
// 품번 셀렉트박스
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<select name="item_part_no_select[]" id="PART_NO_' + itemId + '" class="item-part-no-select" style="width:100%;" required>';
|
|
html += '<option value="">선택</option>';
|
|
html += '</select>';
|
|
html += '<input type="hidden" name="item_objid[]" class="item-objid" value="' + savedItemObjId + '" />';
|
|
html += '<input type="hidden" name="item_part_objid[]" class="item-part-objid" value="' + savedPartObjId + '" />';
|
|
html += '<input type="hidden" name="item_part_no[]" class="item-part-no" value="' + savedPartNo + '" />';
|
|
html += '</td>';
|
|
|
|
// 품명 셀렉트박스
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<select name="item_part_name_select[]" id="PART_NAME_' + itemId + '" class="item-part-name-select" style="width:100%;" required>';
|
|
html += '<option value="">선택</option>';
|
|
html += '</select>';
|
|
html += '<input type="hidden" name="item_part_name[]" class="item-part-name" value="' + savedPartName + '" />';
|
|
html += '</td>';
|
|
|
|
// S/N, 수량, 납기일, 고객요청사항, 반납사유 - 대소문자 처리
|
|
var serialNos = "<%= item.get("SERIAL_NOS") != null ? item.get("SERIAL_NOS") : (item.get("serial_nos") != null ? item.get("serial_nos") : "") %>";
|
|
var quantity = "<%= item.get("QUANTITY") != null ? item.get("QUANTITY") : (item.get("quantity") != null ? item.get("quantity") : "") %>";
|
|
var dueDate = "<%= item.get("DUE_DATE") != null ? item.get("DUE_DATE") : (item.get("due_date") != null ? item.get("due_date") : "") %>";
|
|
// 고객요청사항 - 특수문자 이스케이프 처리
|
|
var customerRequest = <%= new com.google.gson.Gson().toJson(item.get("CUSTOMER_REQUEST") != null ? item.get("CUSTOMER_REQUEST") : (item.get("customer_request") != null ? item.get("customer_request") : "")) %>;
|
|
var returnReason = "<%= item.get("RETURN_REASON") != null ? item.get("RETURN_REASON") : (item.get("return_reason") != null ? item.get("return_reason") : "") %>";
|
|
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<input type="text" name="item_serial_no[]" class="item-serial-no" placeholder="클릭하여 S/N 추가" readonly style="width:95%; padding:5px; cursor:pointer; background-color:#f8f9fa;" onclick="fn_openItemSnPopup(\'' + itemId + '\')" value="' + serialNos + '" />';
|
|
html += '<input type="hidden" name="item_serial_no_list[]" id="' + itemId + '_sn_list" value="" />';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<input type="text" name="item_quantity[]" class="item-quantity" style="width:90%; padding:5px;" value="' + quantity + '" required numberOnly />';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<input type="text" name="item_due_date[]" class="item-due-date date_icon" style="width:90%; padding:5px;" value="' + dueDate + '" />';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<select name="item_return_reason[]" class="item-return-reason select2" style="width:95%;"></select>';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<textarea name="item_customer_request[]" class="item-customer-request" style="width:95%; padding:5px; min-height:34px; resize:vertical; font-family:inherit; font-size:inherit;" rows="1"></textarea>';
|
|
html += '</td>';
|
|
html += '<td style="text-align:center; padding:5px; border:1px solid #ddd;">';
|
|
html += '<button type="button" onclick="fn_deleteItemRow(\'' + itemId + '\')" class="plm_btns" style="padding:5px 10px; font-size:12px;">삭제</button>';
|
|
html += '</td>';
|
|
html += '</tr>';
|
|
|
|
$("#itemListBody").append(html);
|
|
|
|
// 고객요청사항 값 설정 (안전하게 text로 설정)
|
|
if(customerRequest) {
|
|
$("#" + itemId + " .item-customer-request").val(customerRequest);
|
|
}
|
|
|
|
// S/N 데이터 설정 - JSON 객체를 문자열로 변환하여 저장
|
|
var snJsonString = JSON.stringify(snJsonData);
|
|
|
|
// DOM이 완전히 준비된 후 값 설정
|
|
setTimeout(function() {
|
|
$("#" + itemId + "_sn_list").val(snJsonString);
|
|
// 반납사유 select 값 설정
|
|
if(returnReason) {
|
|
$("#" + itemId + " .item-return-reason").val(returnReason).trigger('change');
|
|
}
|
|
}, 10);
|
|
|
|
// 품번/품명 옵션 채우기 (저장된 품번/품명도 함께 전달)
|
|
fn_fillPartOptions(itemId, savedPartObjId, savedPartNo, savedPartName);
|
|
|
|
// 프로젝트가 있으면 품번/품명 셀렉트박스 비활성화 및 삭제 버튼 비활성화
|
|
if(hasProject) {
|
|
$("#PART_NO_" + itemId).prop("disabled", true).css("background-color", "#f5f5f5");
|
|
$("#PART_NAME_" + itemId).prop("disabled", true).css("background-color", "#f5f5f5");
|
|
$("#" + itemId + " button[onclick*='fn_deleteItemRow']").prop("disabled", true).css({
|
|
"background-color": "#ccc",
|
|
"cursor": "not-allowed",
|
|
"opacity": "0.6"
|
|
});
|
|
}
|
|
|
|
// datepicker 적용
|
|
$("#" + itemId + " .date_icon").datepicker({
|
|
changeMonth: true,
|
|
changeYear: true
|
|
});
|
|
|
|
// 반납사유 옵션 추가 및 select2 초기화
|
|
$("#" + itemId + " .item-return-reason").html(returnReasonOptions).select2({
|
|
width: '100%'
|
|
});
|
|
|
|
// 고객요청사항 textarea 자동 높이 조절
|
|
var $textarea = $("#" + itemId + " .item-customer-request");
|
|
$textarea.on('input', function() {
|
|
this.style.height = 'auto';
|
|
this.style.height = (this.scrollHeight) + 'px';
|
|
});
|
|
// 기존 데이터가 있으면 높이 조절 (약간의 지연 후 실행)
|
|
setTimeout(function() {
|
|
if($textarea.val()) {
|
|
$textarea[0].style.height = 'auto';
|
|
$textarea[0].style.height = ($textarea[0].scrollHeight) + 'px';
|
|
}
|
|
}, 50);
|
|
|
|
// 숫자만 입력 처리 및 콤마 추가
|
|
$("#" + itemId + " .item-quantity").on("keyup", function() {
|
|
$(this).val(addComma($(this).val().replace(/[^0-9]/g, "")));
|
|
});
|
|
// 이미 저장된 수량에 콤마 추가
|
|
var qtyInput = $("#" + itemId + " .item-quantity");
|
|
qtyInput.val(addComma(qtyInput.val()));
|
|
|
|
// 품목 정보 저장
|
|
itemList.push({
|
|
id: itemId,
|
|
snList: snJsonData
|
|
});
|
|
})();
|
|
<%
|
|
}
|
|
}
|
|
%>
|
|
}
|
|
|
|
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
|
|
+ "\")'> "
|
|
+ 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; color:#333;">';
|
|
popupHtml += ' <h3 style="margin:0 0 15px 0; text-align:center; color:#333;">S/N 관리</h3>';
|
|
popupHtml += ' <div id="snListContainer" style="margin-bottom:15px; max-height:300px; overflow-y:auto; color:#333;"></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; color:#333;">';
|
|
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; color:#333;">';
|
|
html += '<colgroup><col width="15%"><col width="65%"><col width="20%"></colgroup>';
|
|
html += '<thead><tr style="background:#f5f5f5; color:#333;">';
|
|
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center; color:#333;">번호</th>';
|
|
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center; color:#333;">S/N</th>';
|
|
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center; color:#333;">삭제</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; color:#333;">' + (i+1) + '</td>';
|
|
html += '<td style="padding:8px; border:1px solid #ddd; color:#333;">' + 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; color:#333;">' +
|
|
'<div style="margin-bottom:10px;">' +
|
|
'<label style="display:block; margin-bottom:3px; font-size:13px; color:#333;">시작번호 <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; color:#333;">' +
|
|
'</div>' +
|
|
'<div style="margin-bottom:10px;">' +
|
|
'<label style="display:block; margin-bottom:3px; font-size:13px; color:#333;">생성개수 <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; color:#333;">' +
|
|
'</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('');
|
|
}
|
|
}
|
|
|
|
// ========== 품목 관리 함수 ==========
|
|
|
|
// 프로젝트 존재 여부 확인
|
|
function fn_checkProjectExists() {
|
|
var contractObjId = "${info.OBJID}";
|
|
console.log("=== fn_checkProjectExists 시작 ===");
|
|
console.log("contractObjId:", contractObjId);
|
|
|
|
if(!contractObjId || contractObjId === '') {
|
|
console.log("contractObjId 없음 - 체크 중단");
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: "/contractMgmt/checkProjectExists.do",
|
|
type: "POST",
|
|
data: { contractObjId: contractObjId },
|
|
dataType: "json",
|
|
async: false,
|
|
success: function(data) {
|
|
console.log("AJAX 응답 전체:", data);
|
|
console.log("data.exists 값:", data.exists);
|
|
console.log("data.exists 타입:", typeof data.exists);
|
|
console.log("JSON.stringify(data):", JSON.stringify(data));
|
|
|
|
if(data && data.exists === true) {
|
|
hasProject = true;
|
|
console.log("✅ 프로젝트 존재 확인 - hasProject = true");
|
|
console.log("프로젝트 정보:", data.projectInfo);
|
|
|
|
// 품목 추가 버튼 비활성화
|
|
$("#btnAddItem").prop("disabled", true).css({
|
|
"background-color": "#ccc",
|
|
"cursor": "not-allowed",
|
|
"opacity": "0.6"
|
|
});
|
|
} else {
|
|
console.log("❌ 프로젝트 없음 - hasProject = false");
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error("프로젝트 존재 여부 확인 실패:", error);
|
|
console.error("Status:", status);
|
|
console.error("Response:", xhr.responseText);
|
|
}
|
|
});
|
|
|
|
console.log("=== fn_checkProjectExists 종료 - hasProject:", hasProject, "===");
|
|
}
|
|
|
|
// 품목 행 추가
|
|
function fn_addItemRow() {
|
|
// 프로젝트가 있으면 품목 추가 불가
|
|
if(hasProject) {
|
|
Swal.fire({
|
|
title: '품목 추가 불가',
|
|
text: '프로젝트가 이미 생성되어 품목을 추가할 수 없습니다.\n수량, 납기일 등만 수정 가능합니다.',
|
|
icon: 'warning'
|
|
});
|
|
return;
|
|
}
|
|
|
|
var itemId = 'item_' + itemCounter++;
|
|
|
|
// "품목 추가하세요" 메시지 행 제거
|
|
$("#noItemRow").hide();
|
|
|
|
var html = '<tr id="' + itemId + '" class="item-row">';
|
|
html += '<td style="text-align:center; padding:5px; border:1px solid #ddd;">' + (itemCounter-1) + '</td>';
|
|
|
|
// 품번 셀렉트박스
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<select name="item_part_no_select[]" id="PART_NO_' + itemId + '" class="item-part-no-select" style="width:100%;" required>';
|
|
html += '<option value="">선택</option>';
|
|
html += '</select>';
|
|
html += '<input type="hidden" name="item_objid[]" class="item-objid" value="" />';
|
|
html += '<input type="hidden" name="item_part_objid[]" class="item-part-objid" />';
|
|
html += '<input type="hidden" name="item_part_no[]" class="item-part-no" />';
|
|
html += '</td>';
|
|
|
|
// 품명 셀렉트박스
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<select name="item_part_name_select[]" id="PART_NAME_' + itemId + '" class="item-part-name-select" style="width:100%;" required>';
|
|
html += '<option value="">선택</option>';
|
|
html += '</select>';
|
|
html += '<input type="hidden" name="item_part_name[]" class="item-part-name" />';
|
|
html += '</td>';
|
|
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<input type="text" name="item_serial_no[]" class="item-serial-no" placeholder="클릭하여 S/N 추가" readonly style="width:95%; padding:5px; cursor:pointer; background-color:#f8f9fa;" onclick="fn_openItemSnPopup(\'' + itemId + '\')" />';
|
|
html += '<input type="hidden" name="item_serial_no_list[]" id="' + itemId + '_sn_list" value="" />';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<input type="text" name="item_quantity[]" class="item-quantity" style="width:90%; padding:5px;" required numberOnly />';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<input type="text" name="item_due_date[]" class="item-due-date date_icon" style="width:90%; padding:5px;" />';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<select name="item_return_reason[]" class="item-return-reason select2" style="width:95%;"></select>';
|
|
html += '</td>';
|
|
html += '<td style="padding:5px; border:1px solid #ddd;">';
|
|
html += '<textarea name="item_customer_request[]" class="item-customer-request" style="width:95%; padding:5px; min-height:34px; resize:vertical; font-family:inherit; font-size:inherit;" rows="1"></textarea>';
|
|
html += '</td>';
|
|
html += '<td style="text-align:center; padding:5px; border:1px solid #ddd;">';
|
|
html += '<button type="button" onclick="fn_deleteItemRow(\'' + itemId + '\')" class="plm_btns" style="padding:5px 10px; font-size:12px;">삭제</button>';
|
|
html += '</td>';
|
|
html += '</tr>';
|
|
|
|
$("#itemListBody").append(html);
|
|
|
|
// 품번/품명 옵션 채우기 (신규 추가)
|
|
fn_fillPartOptions(itemId, null, null, null);
|
|
|
|
// 추가된 행의 날짜 필드에 datepicker 적용
|
|
$("#" + itemId + " .date_icon").datepicker({
|
|
changeMonth: true,
|
|
changeYear: true
|
|
});
|
|
|
|
// 반납사유 옵션 추가 및 select2 초기화
|
|
$("#" + itemId + " .item-return-reason").html(returnReasonOptions).select2({
|
|
width: '100%'
|
|
});
|
|
|
|
// 고객요청사항 textarea 자동 높이 조절
|
|
$("#" + itemId + " .item-customer-request").on('input', function() {
|
|
this.style.height = 'auto';
|
|
this.style.height = (this.scrollHeight) + 'px';
|
|
});
|
|
|
|
// 숫자만 입력 처리
|
|
$("#" + itemId + " .item-quantity").on("keyup", function() {
|
|
$(this).val(addComma($(this).val().replace(/[^0-9]/g, "")));
|
|
});
|
|
|
|
// 품목 정보 저장
|
|
itemList.push({
|
|
id: itemId,
|
|
snList: []
|
|
});
|
|
}
|
|
|
|
// 품번/품명 셀렉트박스 옵션 채우기 (Select2 AJAX)
|
|
function fn_fillPartOptions(itemId, selectedObjId, savedPartNo, savedPartName) {
|
|
var $partNoSelect = $("#PART_NO_" + itemId);
|
|
var $partNameSelect = $("#PART_NAME_" + itemId);
|
|
|
|
// null 문자열 체크
|
|
if(selectedObjId === "null" || !selectedObjId) selectedObjId = null;
|
|
if(savedPartNo === "null" || !savedPartNo) savedPartNo = null;
|
|
if(savedPartName === "null" || !savedPartName) savedPartName = null;
|
|
|
|
// partObjId는 있는데 partNo/partName이 없는 경우 -> DB에서 조회
|
|
if(selectedObjId && (!savedPartNo || !savedPartName)) {
|
|
console.log("품번/품명 정보 없음. OBJID로 조회:", selectedObjId);
|
|
$.ajax({
|
|
url: '/contractMgmt/searchPartList.do',
|
|
type: 'POST',
|
|
data: { partObjId: selectedObjId },
|
|
async: false, // 동기 처리
|
|
success: function(data) {
|
|
if(data && data.length > 0) {
|
|
var part = data[0];
|
|
savedPartNo = part.PART_NO || part.part_no;
|
|
savedPartName = part.PART_NAME || part.part_name;
|
|
console.log("조회된 품번/품명:", savedPartNo, savedPartName);
|
|
}
|
|
},
|
|
error: function() {
|
|
console.error("품번/품명 조회 실패");
|
|
}
|
|
});
|
|
}
|
|
|
|
// 품번 Select2 AJAX 설정
|
|
$partNoSelect.select2({
|
|
placeholder: "품번 입력하여 검색...",
|
|
allowClear: true,
|
|
width: '100%',
|
|
minimumInputLength: 1, // 최소 1글자 입력해야 검색
|
|
language: {
|
|
inputTooShort: function() {
|
|
return "최소 1글자 이상 입력하세요";
|
|
},
|
|
searching: function() {
|
|
return "검색 중...";
|
|
},
|
|
noResults: function() {
|
|
return "검색 결과가 없습니다";
|
|
}
|
|
},
|
|
ajax: {
|
|
url: '/contractMgmt/searchPartList.do',
|
|
dataType: 'json',
|
|
type: 'POST',
|
|
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
delay: 250, // 입력 후 250ms 대기
|
|
data: function(params) {
|
|
return {
|
|
searchTerm: params.term // 검색어
|
|
};
|
|
},
|
|
processResults: function(data) {
|
|
console.log("품번 검색 결과:", data);
|
|
if(data && data.length > 0) {
|
|
console.log("첫번째 항목:", data[0]);
|
|
}
|
|
|
|
// 서버 응답을 Select2 형식으로 변환 (대소문자 모두 확인)
|
|
var results = $.map(data, function(item) {
|
|
var objId = item.OBJID || item.objid || item.objId;
|
|
var partNo = item.PART_NO || item.part_no || item.partNo;
|
|
var partName = item.PART_NAME || item.part_name || item.partName;
|
|
|
|
return {
|
|
id: objId,
|
|
text: partNo,
|
|
partName: partName,
|
|
partNo: partNo
|
|
};
|
|
});
|
|
|
|
console.log("변환된 결과:", results);
|
|
|
|
return {
|
|
results: results
|
|
};
|
|
},
|
|
cache: true
|
|
}
|
|
});
|
|
|
|
// 품명 Select2 AJAX 설정
|
|
$partNameSelect.select2({
|
|
placeholder: "품명 입력하여 검색...",
|
|
allowClear: true,
|
|
width: '100%',
|
|
minimumInputLength: 1,
|
|
language: {
|
|
inputTooShort: function() {
|
|
return "최소 1글자 이상 입력하세요";
|
|
},
|
|
searching: function() {
|
|
return "검색 중...";
|
|
},
|
|
noResults: function() {
|
|
return "검색 결과가 없습니다";
|
|
}
|
|
},
|
|
ajax: {
|
|
url: '/contractMgmt/searchPartList.do',
|
|
dataType: 'json',
|
|
type: 'POST',
|
|
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
delay: 250,
|
|
data: function(params) {
|
|
return {
|
|
searchTerm: params.term
|
|
};
|
|
},
|
|
processResults: function(data) {
|
|
console.log("품명 검색 결과:", data);
|
|
if(data && data.length > 0) {
|
|
console.log("첫번째 항목:", data[0]);
|
|
}
|
|
|
|
var results = $.map(data, function(item) {
|
|
var objId = item.OBJID || item.objid || item.objId;
|
|
var partNo = item.PART_NO || item.part_no || item.partNo;
|
|
var partName = item.PART_NAME || item.part_name || item.partName;
|
|
|
|
return {
|
|
id: objId,
|
|
text: partName,
|
|
partName: partName,
|
|
partNo: partNo
|
|
};
|
|
});
|
|
|
|
console.log("변환된 결과:", results);
|
|
|
|
return {
|
|
results: results
|
|
};
|
|
},
|
|
cache: true
|
|
}
|
|
});
|
|
|
|
// 품번 선택 이벤트 (select2:select는 같은 값 재선택 시에도 발생)
|
|
$partNoSelect.off('select2:select').on('select2:select', function(e) {
|
|
var selectedData = e.params.data;
|
|
|
|
if(selectedData && selectedData.id) {
|
|
// 무한루프 방지
|
|
$partNameSelect.data('syncing', true);
|
|
|
|
// 품명 셀렉트박스에 옵션이 없으면 추가
|
|
if($partNameSelect.find("option[value='" + selectedData.id + "']").length === 0) {
|
|
var newOption = new Option(selectedData.partName, selectedData.id, true, true);
|
|
$(newOption).data('partNo', selectedData.partNo);
|
|
$partNameSelect.append(newOption);
|
|
}
|
|
|
|
// 품명 셀렉트박스 값 설정
|
|
$partNameSelect.val(selectedData.id).trigger('change.select2');
|
|
|
|
// hidden 필드에 값 설정
|
|
var $row = $("#" + itemId);
|
|
$row.find(".item-part-objid").val(selectedData.id);
|
|
$row.find(".item-part-no").val(selectedData.partNo);
|
|
$row.find(".item-part-name").val(selectedData.partName);
|
|
|
|
console.log("품번 선택 후 hidden 필드 설정:", {
|
|
itemId: itemId,
|
|
partObjId: $row.find(".item-part-objid").val(),
|
|
partNo: $row.find(".item-part-no").val(),
|
|
partName: $row.find(".item-part-name").val()
|
|
});
|
|
|
|
setTimeout(function() {
|
|
$partNameSelect.data('syncing', false);
|
|
}, 100);
|
|
}
|
|
});
|
|
|
|
// 품명 선택 이벤트 (select2:select는 같은 값 재선택 시에도 발생)
|
|
$partNameSelect.off('select2:select').on('select2:select', function(e) {
|
|
// 무한루프 방지
|
|
if($(this).data('syncing')) return;
|
|
|
|
var selectedData = e.params.data;
|
|
|
|
if(selectedData && selectedData.id) {
|
|
// 무한루프 방지
|
|
$partNoSelect.data('syncing', true);
|
|
|
|
// 품번 셀렉트박스에 옵션이 없으면 추가
|
|
if($partNoSelect.find("option[value='" + selectedData.id + "']").length === 0) {
|
|
var newOption = new Option(selectedData.partNo, selectedData.id, true, true);
|
|
$(newOption).data('partName', selectedData.partName);
|
|
$partNoSelect.append(newOption);
|
|
}
|
|
|
|
// 품번 셀렉트박스 값 설정
|
|
$partNoSelect.val(selectedData.id).trigger('change.select2');
|
|
|
|
// hidden 필드에 값 설정
|
|
var $row = $("#" + itemId);
|
|
$row.find(".item-part-objid").val(selectedData.id);
|
|
$row.find(".item-part-no").val(selectedData.partNo);
|
|
$row.find(".item-part-name").val(selectedData.partName);
|
|
|
|
console.log("품명 선택 후 hidden 필드 설정:", {
|
|
itemId: itemId,
|
|
partObjId: $row.find(".item-part-objid").val(),
|
|
partNo: $row.find(".item-part-no").val(),
|
|
partName: $row.find(".item-part-name").val()
|
|
});
|
|
|
|
setTimeout(function() {
|
|
$partNoSelect.data('syncing', false);
|
|
}, 100);
|
|
}
|
|
});
|
|
|
|
// 기존 선택값이 있으면 로드 (수정 모드)
|
|
console.log("기존 데이터 로드 체크:", {objId: selectedObjId, partNo: savedPartNo, partName: savedPartName});
|
|
|
|
if(selectedObjId && savedPartNo && savedPartName) {
|
|
console.log("기존 데이터 로드 실행");
|
|
|
|
// Select2 초기화 전에 옵션 추가
|
|
var partNoOption = new Option(savedPartNo, selectedObjId, true, true);
|
|
$partNoSelect.append(partNoOption);
|
|
|
|
var partNameOption = new Option(savedPartName, selectedObjId, true, true);
|
|
$partNameSelect.append(partNameOption);
|
|
|
|
// hidden 필드에도 직접 값 설정 (이벤트 트리거 없이)
|
|
$("#" + itemId + " .item-part-objid").val(selectedObjId);
|
|
$("#" + itemId + " .item-part-no").val(savedPartNo);
|
|
$("#" + itemId + " .item-part-name").val(savedPartName);
|
|
|
|
// Select2 수동 업데이트 (무한루프 방지 플래그 설정)
|
|
$partNoSelect.data('syncing', true);
|
|
$partNameSelect.data('syncing', true);
|
|
|
|
$partNoSelect.trigger('change');
|
|
$partNameSelect.trigger('change');
|
|
|
|
setTimeout(function() {
|
|
$partNoSelect.data('syncing', false);
|
|
$partNameSelect.data('syncing', false);
|
|
}, 100);
|
|
} else {
|
|
console.log("기존 데이터 없음 - 신규 등록");
|
|
}
|
|
}
|
|
|
|
|
|
// 품목 행 삭제
|
|
function fn_deleteItemRow(itemId) {
|
|
// 프로젝트가 있으면 품목 삭제 불가
|
|
if(hasProject) {
|
|
Swal.fire({
|
|
title: '품목 삭제 불가',
|
|
text: '프로젝트가 이미 생성되어 품목을 삭제할 수 없습니다.',
|
|
icon: 'warning'
|
|
});
|
|
return;
|
|
}
|
|
|
|
if(confirm("해당 품목을 삭제하시겠습니까?")) {
|
|
$("#" + itemId).remove();
|
|
|
|
// itemList에서 제거
|
|
for(var i = 0; i < itemList.length; i++) {
|
|
if(itemList[i].id == itemId) {
|
|
itemList.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 행 번호 재정렬
|
|
fn_reorderItemRows();
|
|
|
|
// 모든 행이 삭제되면 안내 메시지 표시
|
|
if($(".item-row").length == 0) {
|
|
$("#noItemRow").show();
|
|
}
|
|
}
|
|
}
|
|
|
|
// 품목 행 번호 재정렬
|
|
function fn_reorderItemRows() {
|
|
$(".item-row").each(function(index) {
|
|
$(this).find("td:first").text(index + 1);
|
|
});
|
|
}
|
|
|
|
// 품목별 S/N 관리 팝업
|
|
var currentItemId = '';
|
|
var currentItemSnList = [];
|
|
var itemSnCounter = 1;
|
|
|
|
function fn_openItemSnPopup(itemId) {
|
|
currentItemId = itemId;
|
|
|
|
// 해당 품목의 S/N 목록 로드
|
|
var snListValue = $("#" + itemId + "_sn_list").val();
|
|
currentItemSnList = [];
|
|
|
|
if(snListValue && snListValue.trim() != '') {
|
|
try {
|
|
currentItemSnList = JSON.parse(snListValue);
|
|
if(currentItemSnList.length > 0) {
|
|
var maxId = Math.max.apply(Math, currentItemSnList.map(function(item) { return item.id; }));
|
|
itemSnCounter = maxId + 1;
|
|
}
|
|
} catch(e) {
|
|
currentItemSnList = [];
|
|
}
|
|
}
|
|
|
|
// 팝업 HTML 생성
|
|
var popupHtml = '<div style="padding:10px; color:#333;">';
|
|
popupHtml += ' <h3 style="margin:0 0 15px 0; text-align:center; color:#333;">S/N 관리</h3>';
|
|
popupHtml += ' <div id="itemSnListContainer" style="margin-bottom:15px; max-height:300px; overflow-y:auto; color:#333;"></div>';
|
|
popupHtml += ' <div style="margin-bottom:15px; display:flex; gap:5px;">';
|
|
popupHtml += ' <input type="text" id="newItemSnInput" placeholder="S/N 입력" style="flex:1; padding:8px; border:1px solid #ddd; border-radius:4px; color:#333;">';
|
|
popupHtml += ' <button type="button" onclick="fn_addItemSn()" 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_openItemSequentialSnPopup()" class="plm_btns">연속번호생성</button>';
|
|
popupHtml += ' <button type="button" onclick="fn_confirmItemSnList()" class="plm_btns">확인</button>';
|
|
popupHtml += ' <button type="button" onclick="fn_closeItemSnPopup()" class="plm_btns">취소</button>';
|
|
popupHtml += ' </div>';
|
|
popupHtml += '</div>';
|
|
|
|
// 팝업 오픈
|
|
Swal.fire({
|
|
html: popupHtml,
|
|
width: '700px',
|
|
showConfirmButton: false,
|
|
showCloseButton: true,
|
|
customClass: {
|
|
popup: 'sn-manage-popup'
|
|
},
|
|
onOpen: function() {
|
|
setTimeout(function() {
|
|
fn_renderItemSnList();
|
|
// 엔터키로 추가
|
|
$(".swal2-html-container #newItemSnInput").keypress(function(e) {
|
|
if(e.which == 13) {
|
|
fn_addItemSn();
|
|
return false;
|
|
}
|
|
});
|
|
}, 50);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 품목 S/N 목록 렌더링
|
|
function fn_renderItemSnList() {
|
|
var html = '<table style="width:100%; margin-bottom:10px; border-collapse:collapse; border:1px solid #ddd; color:#333;">';
|
|
html += '<colgroup><col width="15%"><col width="65%"><col width="20%"></colgroup>';
|
|
html += '<thead><tr style="background:#f5f5f5; color:#333;">';
|
|
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center; color:#333;">번호</th>';
|
|
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center; color:#333;">S/N</th>';
|
|
html += '<th style="padding:10px; border:1px solid #ddd; text-align:center; color:#333;">삭제</th>';
|
|
html += '</tr></thead>';
|
|
html += '<tbody>';
|
|
|
|
if(currentItemSnList.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 < currentItemSnList.length; i++) {
|
|
html += '<tr>';
|
|
html += '<td style="text-align:center; padding:8px; border:1px solid #ddd; color:#333;">' + (i+1) + '</td>';
|
|
html += '<td style="padding:8px; border:1px solid #ddd; color:#333;">' + currentItemSnList[i].value + '</td>';
|
|
html += '<td style="text-align:center; padding:8px; border:1px solid #ddd;">';
|
|
html += '<button type="button" onclick="fn_deleteItemSn(' + currentItemSnList[i].id + ')" class="plm_btns" style="padding:5px 10px; font-size:12px;">삭제</button>';
|
|
html += '</td>';
|
|
html += '</tr>';
|
|
}
|
|
}
|
|
|
|
html += '</tbody></table>';
|
|
|
|
$(".swal2-html-container #itemSnListContainer").html(html);
|
|
}
|
|
|
|
// 품목 S/N 추가
|
|
function fn_addItemSn() {
|
|
var newSn = $(".swal2-html-container #newItemSnInput").val().trim();
|
|
|
|
if(newSn == '') {
|
|
alert('S/N을 입력해주세요.');
|
|
return;
|
|
}
|
|
|
|
// 중복 체크
|
|
for(var i = 0; i < currentItemSnList.length; i++) {
|
|
if(currentItemSnList[i].value == newSn) {
|
|
alert('이미 등록된 S/N입니다.');
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 추가
|
|
currentItemSnList.push({
|
|
id: itemSnCounter++,
|
|
value: newSn
|
|
});
|
|
|
|
$(".swal2-html-container #newItemSnInput").val('');
|
|
fn_renderItemSnList();
|
|
}
|
|
|
|
// 품목 S/N 삭제
|
|
function fn_deleteItemSn(snId) {
|
|
for(var i = 0; i < currentItemSnList.length; i++) {
|
|
if(currentItemSnList[i].id == snId) {
|
|
currentItemSnList.splice(i, 1);
|
|
break;
|
|
}
|
|
}
|
|
fn_renderItemSnList();
|
|
}
|
|
|
|
// 품목 연속번호 생성 팝업
|
|
function fn_openItemSequentialSnPopup() {
|
|
Swal.fire({
|
|
title: '연속번호 생성',
|
|
html:
|
|
'<div style="text-align:left; padding:5px; color:#333;">' +
|
|
'<div style="margin-bottom:10px;">' +
|
|
'<label style="display:block; margin-bottom:3px; font-size:13px; color:#333;">시작번호 <span style="color:red;">*</span></label>' +
|
|
'<input type="text" id="itemSeqStartNo" placeholder="예: ITEM-001" style="width:100%; padding:6px; border:1px solid #ddd; border-radius:3px; font-size:13px; color:#333;">' +
|
|
'</div>' +
|
|
'<div style="margin-bottom:10px;">' +
|
|
'<label style="display:block; margin-bottom:3px; font-size:13px; color:#333;">생성개수 <span style="color:red;">*</span></label>' +
|
|
'<input type="number" id="itemSeqCount" placeholder="예: 10" min="1" max="100" style="width:100%; padding:6px; border:1px solid #ddd; border-radius:3px; font-size:13px; color:#333;">' +
|
|
'</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('itemSeqStartNo').value.trim();
|
|
const count = parseInt(document.getElementById('itemSeqCount').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_generateItemSequentialSn(result.value.startNo, result.value.count);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 품목 연속번호 생성
|
|
function fn_generateItemSequentialSn(startNo, count) {
|
|
var match = startNo.match(/^(.*?)(\d+)$/);
|
|
|
|
if(!match) {
|
|
alert('올바른 형식이 아닙니다. 마지막에 숫자가 있어야 합니다. (예: ITEM-001)');
|
|
fn_openItemSequentialSnPopup();
|
|
return;
|
|
}
|
|
|
|
var prefix = match[1];
|
|
var startNum = parseInt(match[2]);
|
|
var numLength = match[2].length;
|
|
|
|
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 < currentItemSnList.length; j++) {
|
|
if(currentItemSnList[j].value == newSn) {
|
|
isDuplicate = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!isDuplicate) {
|
|
currentItemSnList.push({
|
|
id: itemSnCounter++,
|
|
value: newSn
|
|
});
|
|
addedCount++;
|
|
}
|
|
}
|
|
|
|
// 저장 후 팝업 재오픈
|
|
$("#" + currentItemId + "_sn_list").val(JSON.stringify(currentItemSnList));
|
|
fn_openItemSnPopup(currentItemId);
|
|
}
|
|
|
|
// 품목 S/N 확인
|
|
function fn_confirmItemSnList() {
|
|
// hidden 필드에 저장
|
|
var jsonString = JSON.stringify(currentItemSnList);
|
|
$("#" + currentItemId + "_sn_list").val(jsonString);
|
|
|
|
// display 필드에 표시
|
|
var snValues = [];
|
|
for(var i = 0; i < currentItemSnList.length; i++) {
|
|
snValues.push(currentItemSnList[i].value);
|
|
}
|
|
$("#" + currentItemId + " .item-serial-no").val(snValues.join(', '));
|
|
|
|
// itemList 업데이트
|
|
for(var i = 0; i < itemList.length; i++) {
|
|
if(itemList[i].id == currentItemId) {
|
|
itemList[i].snList = currentItemSnList;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Swal.close();
|
|
}
|
|
|
|
// 품목 S/N 팝업 닫기
|
|
function fn_closeItemSnPopup() {
|
|
Swal.close();
|
|
}
|
|
|
|
</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="">
|
|
|
|
<!-- 반납사유 공통코드 템플릿 (숨김) -->
|
|
<select id="return_reason_template" style="display:none;">
|
|
<option value="">선택</option>
|
|
${code_map.return_reason_cd}
|
|
</select>
|
|
|
|
<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>
|
|
<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" ${info.PAID_TYPE eq 'paid' ? 'selected' : ''}>유상</option>
|
|
<option value="free" ${info.PAID_TYPE eq 'free' ? 'selected' : ''}>무상</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>
|
|
<td class="input_title"><label for="">견적환종</label></td>
|
|
<td>
|
|
<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>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<!-- 품목정보 영역 -->
|
|
<div class="form_popup_title" style="margin-top:15px;">
|
|
<span>품목정보</span>
|
|
<button type="button" id="btnAddItem" class="plm_btns" style="float:right; margin-top:-5px;">품목 추가</button>
|
|
</div>
|
|
<table class="">
|
|
<colgroup>
|
|
<col width="100%" />
|
|
</colgroup>
|
|
<tr>
|
|
<td>
|
|
<div style="max-height:300px; overflow-y:auto;">
|
|
<table class="pmsPopuptable" id="itemListTable">
|
|
<colgroup>
|
|
<col width="4%" /> <!-- 번호 -->
|
|
<col width="12%" /> <!-- 품번 -->
|
|
<col width="12%" /> <!-- 품명 -->
|
|
<col width="15%" /> <!-- S/N -->
|
|
<col width="7%" /> <!-- 수량 -->
|
|
<col width="10%" /> <!-- 요청납기 -->
|
|
<col width="15%" /> <!-- 반납사유 -->
|
|
<col width="20%" /> <!-- 고객요청사항 -->
|
|
<col width="5%" /> <!-- 삭제 -->
|
|
</colgroup>
|
|
<thead>
|
|
<tr style="background:#f5f5f5;">
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">No</th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">품번 <span style="color:red;">*</span></th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">품명 <span style="color:red;">*</span></th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">S/N</th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">견적수량 <span style="color:red;">*</span></th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">요청납기</th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">반납사유</th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">고객요청사항</th>
|
|
<th style="text-align:center; padding:8px; border:1px solid #ddd;">삭제</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="itemListBody">
|
|
<!-- 품목 행이 동적으로 추가됩니다 -->
|
|
<tr id="noItemRow">
|
|
<td colspan="9" style="text-align:center; padding:30px; color:#999;">
|
|
품목 추가 버튼을 클릭하여 품목을 등록하세요.
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<table class="">
|
|
<colgroup>
|
|
<col width="100%" />
|
|
</colgroup>
|
|
<tr>
|
|
<td>
|
|
<table class="pmsPopuptable">
|
|
|
|
<!-- 이전 필드들 (주석처리되어 보존) -->
|
|
<%--
|
|
<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> |