분할출하 S/N 입력하는 부분 수정, 디자인 기존과 동일하게 변경
This commit is contained in:
@@ -1,22 +1,45 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ include file="/init.jsp" %>
|
||||
<%@ include file="/init_new.jsp" %>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>분할출하 등록</title>
|
||||
<link rel="stylesheet" href="/css/ions-basic.css">
|
||||
<script type="text/javascript" src="/js/ions-common.js" ></script>
|
||||
<script>
|
||||
// S/N 관리 전역 변수
|
||||
var snList = [];
|
||||
var snCounter = 1;
|
||||
|
||||
$(document).ready(function() {
|
||||
// select2 초기화
|
||||
$('.select2').select2();
|
||||
|
||||
// 달력 초기화
|
||||
fnc_makeDatepick();
|
||||
_fnc_datepick();
|
||||
|
||||
// 분할수량 자동 입력
|
||||
$("#splitQuantity").val("${param.splitQuantity}");
|
||||
|
||||
// S/N 필드 클릭 이벤트
|
||||
$("#serialNo").click(function() {
|
||||
fn_openSnManagePopup();
|
||||
});
|
||||
|
||||
// 페이지 로드 시 기존 S/N 데이터가 있으면 파싱
|
||||
var initialSnValue = $("#serialNo").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) {
|
||||
$("#serialNoList").val(JSON.stringify(initialSnList));
|
||||
snCounter = initialSnList.length + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 닫기 버튼
|
||||
$("#btnClose").click(function() {
|
||||
@@ -42,6 +65,23 @@
|
||||
$("#splitQuantity").focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// S/N 데이터 처리: JSON에서 값만 추출하여 콤마로 연결
|
||||
var serialNoListValue = $("#serialNoList").val();
|
||||
if(serialNoListValue && serialNoListValue.trim() != '') {
|
||||
try {
|
||||
var snArray = JSON.parse(serialNoListValue);
|
||||
var snValues = [];
|
||||
for(var i = 0; i < snArray.length; i++) {
|
||||
if(snArray[i].value) {
|
||||
snValues.push(snArray[i].value);
|
||||
}
|
||||
}
|
||||
$("#serialNo").val(snValues.join(','));
|
||||
} catch(e) {
|
||||
console.error("S/N JSON 파싱 오류:", e);
|
||||
}
|
||||
}
|
||||
|
||||
if(confirm("분할출하를 등록하시겠습니까?")) {
|
||||
$.ajax({
|
||||
@@ -53,9 +93,9 @@
|
||||
alert(data.msg);
|
||||
if (data.result) {
|
||||
if(opener && opener.fn_search) {
|
||||
opener.fn_search(); // 부모창 그리드 새로고침
|
||||
opener.fn_search();
|
||||
}
|
||||
window.close(); // 팝업 닫기
|
||||
window.close();
|
||||
}
|
||||
},
|
||||
error: function(jqxhr, status, error) {
|
||||
@@ -65,6 +105,219 @@
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// S/N 화면 표시 업데이트
|
||||
function fn_updateSnDisplay() {
|
||||
var count = snList.length;
|
||||
if(count > 0) {
|
||||
var snValues = [];
|
||||
for(var i = 0; i < snList.length; i++) {
|
||||
snValues.push(snList[i].value);
|
||||
}
|
||||
$("#serialNo").val(snValues.join(', '));
|
||||
} else {
|
||||
$("#serialNo").val('');
|
||||
}
|
||||
}
|
||||
|
||||
// S/N 관리 팝업 열기
|
||||
function fn_openSnManagePopup() {
|
||||
var serialNoListValue = $("#serialNoList").val();
|
||||
|
||||
if(serialNoListValue && serialNoListValue.trim() != '') {
|
||||
try {
|
||||
snList = JSON.parse(serialNoListValue);
|
||||
if(snList.length > 0) {
|
||||
var maxId = Math.max.apply(Math, snList.map(function(item) { return item.id; }));
|
||||
snCounter = maxId + 1;
|
||||
}
|
||||
} catch(e) {
|
||||
snList = [];
|
||||
}
|
||||
} else {
|
||||
var serialNoValue = $("#serialNo").val();
|
||||
if(serialNoValue && serialNoValue.trim() != '') {
|
||||
snList = [];
|
||||
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 {
|
||||
snList = [];
|
||||
}
|
||||
}
|
||||
|
||||
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.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() {
|
||||
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;">번호</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><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:4px 8px; font-size:12px;">삭제</button>';
|
||||
html += '</td></tr>';
|
||||
}
|
||||
}
|
||||
html += '</tbody></table>';
|
||||
$(".swal2-html-container #snListContainer").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: () => {
|
||||
var startNo = $("#seqStartNo").val().trim();
|
||||
var count = parseInt($("#seqCount").val());
|
||||
if(!startNo) { Swal.showValidationMessage('시작번호를 입력해주세요.'); return false; }
|
||||
if(!count || count < 1) { Swal.showValidationMessage('생성개수를 입력해주세요.'); return false; }
|
||||
if(count > 100) { Swal.showValidationMessage('최대 100개까지 생성 가능합니다.'); return false; }
|
||||
return {startNo: startNo, count: count};
|
||||
}
|
||||
}).then((result) => {
|
||||
if(result.isConfirmed && result.value) {
|
||||
fn_generateSequentialSn(result.value.startNo, result.value.count);
|
||||
} else {
|
||||
fn_openSnManagePopup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 연속번호 생성 로직
|
||||
function fn_generateSequentialSn(startNo, count) {
|
||||
var match = startNo.match(/^(.*?)(\d+)$/);
|
||||
if(!match) {
|
||||
alert('올바른 형식이 아닙니다. 마지막에 숫자가 있어야 합니다. (예: ITEM-001)');
|
||||
fn_openSequentialSnPopup();
|
||||
return;
|
||||
}
|
||||
var prefix = match[1];
|
||||
var startNum = parseInt(match[2]);
|
||||
var numLength = match[2].length;
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
||||
$("#serialNoList").val(JSON.stringify(snList));
|
||||
fn_openSnManagePopup();
|
||||
}
|
||||
|
||||
// S/N 목록 확인 및 적용
|
||||
function fn_confirmSnList() {
|
||||
var snValues = [];
|
||||
for(var i = 0; i < snList.length; i++) { snValues.push(snList[i].value); }
|
||||
$("#serialNoList").val(JSON.stringify(snList));
|
||||
fn_updateSnDisplay();
|
||||
Swal.close();
|
||||
}
|
||||
|
||||
// S/N 팝업 닫기
|
||||
function fn_closeSnPopup() {
|
||||
Swal.close();
|
||||
}
|
||||
|
||||
// 날짜 선택기 초기화
|
||||
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
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -74,122 +327,148 @@
|
||||
<input type="hidden" name="originalQuantity" value="${not empty info ? info.QUANTITY : param.originalQuantity}">
|
||||
<input type="hidden" name="contractObjid" value="${info.CONTRACT_OBJID}">
|
||||
<input type="hidden" name="partObjid" value="${info.PART_OBJID}">
|
||||
<input type="hidden" name="orderUnitPrice" value="${info.ORDER_UNIT_PRICE}">
|
||||
<input type="hidden" name="exchangeRate" value="${info.EXCHANGE_RATE}">
|
||||
<input type="hidden" name="contractCurrency" value="${info.CONTRACT_CURRENCY}">
|
||||
<!-- S/N JSON 데이터 저장용 (클라이언트 전용) -->
|
||||
<input type="hidden" id="serialNoList" value="" />
|
||||
|
||||
<section>
|
||||
<section class="business_popup_min_width">
|
||||
<div class="plm_menu_name">
|
||||
<h2>
|
||||
<span>분할출하 등록</span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div id="businessPopupFormWrap" >
|
||||
<table class="pmsPopupForm">
|
||||
<div id="EntirePopupFormWrap">
|
||||
<table class="">
|
||||
<colgroup>
|
||||
<col width="15%"/>
|
||||
<col width="35%"/>
|
||||
<col width="15%"/>
|
||||
<col width="35%"/>
|
||||
<col width="100%" />
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="4" style="height:15px;"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="projectNo">프로젝트번호</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${not empty info ? info.PROJECT_NO : param.projectNo}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
<td class="input_title"><label for="originalQuantity">원본수량</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${not empty info ? info.QUANTITY : param.originalQuantity}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="partNo">품번</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${info.PART_NO}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
<td class="input_title"><label for="partName">품명</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${info.PART_NAME}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="customer">고객사</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${info.CUSTOMER}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
<td class="input_title"><label for="poNo">발주번호</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${info.PO_NO}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="remainingQuantity">잔여수량</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${info.REMAINING_QUANTITY}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
<td class="input_title"><label for="salesQuantity">출하수량</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" value="${info.SALES_QUANTITY}" disabled style="width:100%; background-color:#f0f0f0;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="splitQuantity">* 분할수량</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="number" name="splitQuantity" id="splitQuantity" style="width:100%;" required />
|
||||
</td>
|
||||
<td class="input_title"><label for="serialNo">S/N</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" name="serialNo" id="serialNo" style="width:100%;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="shippingDate">* 출고일</label></td>
|
||||
<td class="input_sub_title">
|
||||
<input type="text" id="shippingDate" name="shippingDate" required class="date_icon" style="width: 100px !important;background-color:#fff;" autocomplete="off" />
|
||||
</td>
|
||||
<td class="input_title"><label for="shippingMethod">출고방법</label></td>
|
||||
<td class="input_sub_title">
|
||||
<select name="shippingMethod" id="shippingMethod" type="select" style="width:100%;" class="select2">
|
||||
<option value="">선택</option>
|
||||
<option value="D_D">내수/직납</option>
|
||||
<option value="D_P">내수/택배</option>
|
||||
<option value="D_E">내수/기타</option>
|
||||
<option value="E">수출</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="manager">담당자</label></td>
|
||||
<td class="input_sub_title">
|
||||
<select name="manager" id="manager" type="select" style="width:100%;" class="select2">
|
||||
<option value="">선택</option>
|
||||
${codeMap.managerList}
|
||||
</select>
|
||||
</td>
|
||||
<td class="input_title"><label for="incoterms">인도조건</label></td>
|
||||
<td class="input_sub_title">
|
||||
<select name="incoterms" id="incoterms" type="select" style="width:100%;" class="select2">
|
||||
<option value="">선택</option>
|
||||
<option value="FOB">FOB</option>
|
||||
<option value="EXW">EXW</option>
|
||||
<option value="CIF">CIF</option>
|
||||
<option value="DDP">DDP</option>
|
||||
<option value="DAP">DAP</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="input_title"><label for="remark">비고</label></td>
|
||||
<td class="input_sub_title" colspan="3">
|
||||
<textarea name="remark" id="remark" style="width:100%; height:60px;"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4" style="height:15px;"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="pmsPopuptable">
|
||||
<colgroup>
|
||||
<col width="15%" />
|
||||
<col width="35%" />
|
||||
<col width="15%" />
|
||||
<col width="35%" />
|
||||
</colgroup>
|
||||
|
||||
<!-- 1행: 프로젝트번호, 원본수량 -->
|
||||
<tr>
|
||||
<td class="input_title"><label>프로젝트번호</label></td>
|
||||
<td>
|
||||
<input type="text" value="${not empty info ? info.PROJECT_NO : param.projectNo}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
<td class="input_title"><label>원본수량</label></td>
|
||||
<td>
|
||||
<input type="text" value="${not empty info ? info.QUANTITY : param.originalQuantity}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 2행: 품번, 품명 -->
|
||||
<tr>
|
||||
<td class="input_title"><label>품번</label></td>
|
||||
<td>
|
||||
<input type="text" value="${info.PART_NO}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
<td class="input_title"><label>품명</label></td>
|
||||
<td>
|
||||
<input type="text" value="${info.PART_NAME}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 3행: 고객사, 발주번호 -->
|
||||
<tr>
|
||||
<td class="input_title"><label>고객사</label></td>
|
||||
<td>
|
||||
<input type="text" value="${info.CUSTOMER}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
<td class="input_title"><label>발주번호</label></td>
|
||||
<td>
|
||||
<input type="text" value="${info.PO_NO}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 4행: 잔여수량, 출하수량 -->
|
||||
<tr>
|
||||
<td class="input_title"><label>잔여수량</label></td>
|
||||
<td>
|
||||
<input type="text" value="${info.REMAINING_QUANTITY}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
<td class="input_title"><label>출하수량</label></td>
|
||||
<td>
|
||||
<input type="text" value="${info.SALES_QUANTITY}" readonly style="background-color:#f5f5f5;" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 5행: 분할수량, S/N -->
|
||||
<tr>
|
||||
<td class="input_title"><label for="splitQuantity">분할수량</label></td>
|
||||
<td>
|
||||
<input type="number" name="splitQuantity" id="splitQuantity" required />
|
||||
</td>
|
||||
<td class="input_title"><label for="serialNo">S/N</label></td>
|
||||
<td>
|
||||
<input type="text" name="serialNo" id="serialNo"
|
||||
placeholder="클릭하여 S/N 추가"
|
||||
style="cursor:pointer; background-color:#f8f9fa; color:#333 !important;"
|
||||
readonly />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 6행: 출고일, 출고방법 -->
|
||||
<tr>
|
||||
<td class="input_title"><label for="shippingDate">출고일</label></td>
|
||||
<td>
|
||||
<input type="text" id="shippingDate" name="shippingDate" required class="date_icon" autocomplete="off" />
|
||||
</td>
|
||||
<td class="input_title"><label for="shippingMethod">출고방법</label></td>
|
||||
<td>
|
||||
<select name="shippingMethod" id="shippingMethod" class="select2">
|
||||
<option value="">선택</option>
|
||||
<option value="D_D">내수/직납</option>
|
||||
<option value="D_P">내수/택배</option>
|
||||
<option value="D_E">내수/기타</option>
|
||||
<option value="E">수출</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 7행: 담당자, 인도조건 -->
|
||||
<tr>
|
||||
<td class="input_title"><label for="manager">담당자</label></td>
|
||||
<td>
|
||||
<select name="manager" id="manager" class="select2">
|
||||
<option value="">선택</option>
|
||||
${codeMap.managerList}
|
||||
</select>
|
||||
</td>
|
||||
<td class="input_title"><label for="incoterms">인도조건</label></td>
|
||||
<td>
|
||||
<select name="incoterms" id="incoterms" class="select2">
|
||||
<option value="">선택</option>
|
||||
<option value="FOB">FOB</option>
|
||||
<option value="EXW">EXW</option>
|
||||
<option value="CIF">CIF</option>
|
||||
<option value="DDP">DDP</option>
|
||||
<option value="DAP">DAP</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 8행: 비고 -->
|
||||
<tr>
|
||||
<td class="input_title"><label for="remark">비고</label></td>
|
||||
<td colspan="3">
|
||||
<textarea name="remark" id="remark" style="width:100%; height:60px;"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -200,7 +479,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -2090,7 +2090,10 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
|
||||
COALESCE(CM.PO_NO, '') AS PO_NO,
|
||||
COALESCE(CM.ORDER_DATE, '') AS ORDER_DATE,
|
||||
COALESCE((SELECT SUM(SR.SALES_QUANTITY) FROM SALES_REGISTRATION SR WHERE SR.PROJECT_NO = T.PROJECT_NO), 0) AS SALES_QUANTITY,
|
||||
COALESCE(T.QUANTITY::NUMERIC, 0) - COALESCE((SELECT SUM(SR.SALES_QUANTITY) FROM SALES_REGISTRATION SR WHERE SR.PROJECT_NO = T.PROJECT_NO), 0) AS REMAINING_QUANTITY
|
||||
COALESCE(T.QUANTITY::NUMERIC, 0) - COALESCE((SELECT SUM(SR.SALES_QUANTITY) FROM SALES_REGISTRATION SR WHERE SR.PROJECT_NO = T.PROJECT_NO), 0) AS REMAINING_QUANTITY,
|
||||
COALESCE(NULLIF(CM.ORDER_UNIT_PRICE, '')::NUMERIC, 0) AS ORDER_UNIT_PRICE,
|
||||
COALESCE(NULLIF(CM.EXCHANGE_RATE, '')::NUMERIC, 1) AS EXCHANGE_RATE,
|
||||
COALESCE(CM.CONTRACT_CURRENCY, '') AS CONTRACT_CURRENCY
|
||||
FROM PROJECT_MGMT T
|
||||
LEFT JOIN CONTRACT_MGMT CM ON CM.OBJID = T.CONTRACT_OBJID
|
||||
LEFT JOIN SUPPLY_MNG SM ON SM.OBJID = CASE WHEN T.CUSTOMER_OBJID ~ '^[0-9]+$' THEN T.CUSTOMER_OBJID::NUMERIC ELSE NULL END
|
||||
|
||||
@@ -360,6 +360,14 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
System.out.println("saleNo (파라미터): " + saleNo);
|
||||
System.out.println("salesQuantity: " + paramMap.get("salesQuantity"));
|
||||
|
||||
// 폼 필드명(manager) → SQL 파라미터명(managerUserId) 매핑
|
||||
if(paramMap.get("manager") != null && !"".equals(paramMap.get("manager"))) {
|
||||
paramMap.put("managerUserId", paramMap.get("manager"));
|
||||
}
|
||||
|
||||
System.out.println("serialNo: " + paramMap.get("serialNo"));
|
||||
System.out.println("manager → managerUserId: " + paramMap.get("managerUserId"));
|
||||
|
||||
// 모든 판매를 shipment_log에 기록 (분할 출하 방식 통일)
|
||||
// 1. 해당 프로젝트의 sales_registration 레코드 확인
|
||||
Map<String, Object> checkParam = new HashMap<String, Object>();
|
||||
@@ -391,9 +399,10 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
baseRecord.put("salesExchangeRate", paramMap.get("salesExchangeRate"));
|
||||
baseRecord.put("shippingDate", paramMap.get("shippingDate"));
|
||||
baseRecord.put("shippingMethod", paramMap.get("shippingMethod"));
|
||||
baseRecord.put("managerUserId", paramMap.get("managerUserId"));
|
||||
baseRecord.put("managerUserId", paramMap.get("managerUserId")); // 위에서 manager → managerUserId 매핑됨
|
||||
baseRecord.put("incoterms", paramMap.get("incoterms"));
|
||||
baseRecord.put("serialNo", paramMap.get("serialNo"));
|
||||
System.out.println("insertSaleRegistration - serialNo: " + paramMap.get("serialNo"));
|
||||
baseRecord.put("shippingOrderStatus", "출하지시"); // 자동으로 출하지시 상태 설정
|
||||
baseRecord.put("cretEmpNo", paramMap.get("cretEmpNo"));
|
||||
|
||||
@@ -495,22 +504,21 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
PersonBean person = (PersonBean) request.getSession().getAttribute(Constants.PERSON_BEAN);
|
||||
String userId = person.getUserId();
|
||||
|
||||
// 원본 데이터 조회
|
||||
Map<String, Object> originalData = sqlSession.selectOne("salesNcollectMgmt.getContractByObjid", paramMap);
|
||||
|
||||
if(originalData == null) {
|
||||
resultMap.put("result", false);
|
||||
resultMap.put("msg", "원본 데이터를 찾을 수 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
// 분할 수량
|
||||
int splitQuantity = Integer.parseInt(paramMap.get("splitQuantity").toString());
|
||||
int originalQuantity = Integer.parseInt(paramMap.get("originalQuantity").toString());
|
||||
|
||||
// 원본 데이터의 단가 정보 가져오기
|
||||
BigDecimal unitPrice = new BigDecimal(originalData.get("order_unit_price").toString());
|
||||
BigDecimal exchangeRate = new BigDecimal(originalData.get("exchange_rate").toString());
|
||||
// 단가/환율은 폼 hidden 필드에서 직접 가져옴 (프로젝트 기반, contract_mgmt 직접 조회 불필요)
|
||||
String unitPriceStr = CommonUtils.checkNull(paramMap.get("orderUnitPrice"));
|
||||
String exchangeRateStr = CommonUtils.checkNull(paramMap.get("exchangeRate"));
|
||||
String contractCurrency = CommonUtils.checkNull(paramMap.get("contractCurrency"));
|
||||
|
||||
BigDecimal unitPrice = StringUtils.isNotBlank(unitPriceStr) ? new BigDecimal(unitPriceStr) : BigDecimal.ZERO;
|
||||
BigDecimal exchangeRate = StringUtils.isNotBlank(exchangeRateStr) ? new BigDecimal(exchangeRateStr) : BigDecimal.ONE;
|
||||
|
||||
System.out.println("=== splitShipment 디버그 ===");
|
||||
System.out.println("projectNo: " + paramMap.get("projectNo"));
|
||||
System.out.println("unitPrice: " + unitPrice + ", exchangeRate: " + exchangeRate + ", currency: " + contractCurrency);
|
||||
|
||||
// 분할 금액 계산
|
||||
BigDecimal splitSupplyPrice = unitPrice.multiply(new BigDecimal(splitQuantity));
|
||||
@@ -527,19 +535,13 @@ public Map<String, Object> saveSaleRegistration(HttpServletRequest request, Map<
|
||||
paramMap.put("salesSupplyPrice", splitSupplyPrice);
|
||||
paramMap.put("salesVat", splitVat);
|
||||
paramMap.put("salesTotalAmount", splitTotalAmount);
|
||||
paramMap.put("salesCurrency", originalData.get("contract_currency"));
|
||||
paramMap.put("salesCurrency", contractCurrency);
|
||||
paramMap.put("salesExchangeRate", exchangeRate);
|
||||
|
||||
// 팝업에서 입력한 데이터 우선, 없으면 원본 데이터 사용
|
||||
paramMap.put("shippingMethod",
|
||||
StringUtils.isNotBlank((String)paramMap.get("shippingMethod")) ?
|
||||
paramMap.get("shippingMethod") : originalData.get("shipping_method"));
|
||||
paramMap.put("incoterms",
|
||||
StringUtils.isNotBlank((String)paramMap.get("incoterms")) ?
|
||||
paramMap.get("incoterms") : originalData.get("incoterms"));
|
||||
paramMap.put("managerUserId",
|
||||
StringUtils.isNotBlank((String)paramMap.get("manager")) ?
|
||||
paramMap.get("manager") : originalData.get("pm_user_id"));
|
||||
// 담당자 매핑 (폼 필드명 manager → SQL 파라미터명 managerUserId)
|
||||
if(StringUtils.isNotBlank((String)paramMap.get("manager"))) {
|
||||
paramMap.put("managerUserId", paramMap.get("manager"));
|
||||
}
|
||||
|
||||
// 팝업에서 입력한 추가 정보
|
||||
// serialNo, shippingDate, remark는 팝업에서만 입력 가능
|
||||
|
||||
Reference in New Issue
Block a user