분할출하 S/N 입력하는 부분 수정, 디자인 기존과 동일하게 변경

This commit is contained in:
2026-02-09 16:02:36 +09:00
parent 2810a7b764
commit 3068354cd0
3 changed files with 423 additions and 139 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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는 팝업에서만 입력 가능