V20260210 #154
@@ -151,6 +151,28 @@ $(document).ready(function(){
|
||||
document.form1.submit();
|
||||
});
|
||||
|
||||
// 수주취소
|
||||
$("#btnOrderCancel").click(function(){
|
||||
var selectedData = _tabulGrid.getSelectedData();
|
||||
if(selectedData.length < 1){
|
||||
Swal.fire("수주취소할 행을 선택해주십시오.");
|
||||
return false;
|
||||
} else if(selectedData.length > 1){
|
||||
Swal.fire("한번에 한개의 수주만 취소 가능합니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var contractObjId = fnc_checkNull(selectedData[0].OBJID);
|
||||
var orderQty = parseInt(selectedData[0].ORDER_QUANTITY) || 0;
|
||||
|
||||
if(orderQty === 0){
|
||||
Swal.fire("수주 수량이 없는 건은 취소할 수 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
fn_openOrderCancelPopup(contractObjId);
|
||||
});
|
||||
|
||||
fn_search();
|
||||
});
|
||||
|
||||
@@ -203,6 +225,14 @@ var columns = [
|
||||
return Number(value).toLocaleString();
|
||||
}
|
||||
},
|
||||
// 8-1. 수주취소
|
||||
{headerHozAlign : 'center', hozAlign : 'right', minWidth : 60, widthGrow: 0.7, title : '수주취소', field : 'CANCEL_QTY_SUM',
|
||||
formatter: function(cell) {
|
||||
var value = cell.getValue();
|
||||
if(!value || value === '' || value === 0 || value === '0') return '';
|
||||
return "<span style='color:#e74c3c; font-weight:bold;'>" + Number(value).toLocaleString() + "</span>";
|
||||
}
|
||||
},
|
||||
// 9. 유/무상
|
||||
{headerHozAlign : 'center', hozAlign : 'center', minWidth : 45, widthGrow: 0.5, title : '유/무상', field : 'PAID_TYPE' },
|
||||
// 10. 수주상태
|
||||
@@ -656,6 +686,131 @@ function fn_showSerialNoPopup(serialNoString){
|
||||
});
|
||||
}
|
||||
|
||||
// 수주취소 팝업 - 품목별 취소 수량 입력
|
||||
function fn_openOrderCancelPopup(contractObjId){
|
||||
$.ajax({
|
||||
url: "/contractMgmt/getContractItems.do",
|
||||
type: "POST",
|
||||
data: { contractObjId: contractObjId },
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.result !== "success" || !data.items || data.items.length === 0){
|
||||
Swal.fire("수주 품목 정보가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
var items = data.items;
|
||||
var html = '<div style="max-height: 400px; overflow-y: auto;">';
|
||||
html += '<table style="width: 100%; border-collapse: collapse;">';
|
||||
html += '<thead><tr style="background-color: #f0f0f0;">';
|
||||
html += '<th style="border: 1px solid #ddd; padding: 8px;">품번</th>';
|
||||
html += '<th style="border: 1px solid #ddd; padding: 8px;">품명</th>';
|
||||
html += '<th style="border: 1px solid #ddd; padding: 8px;">수주수량</th>';
|
||||
html += '<th style="border: 1px solid #ddd; padding: 8px;">취소수량</th>';
|
||||
html += '</tr></thead><tbody>';
|
||||
|
||||
items.forEach(function(item, idx){
|
||||
var objid = item.OBJID || item.objid || '';
|
||||
var partNo = item.PART_NO || item.part_no || '';
|
||||
var partName = item.PART_NAME || item.part_name || '';
|
||||
var orderQty = item.ORDER_QUANTITY || item.order_quantity || '0';
|
||||
var cancelQty = item.CANCEL_QTY || item.cancel_qty || '';
|
||||
var orderQtyNum = parseInt(orderQty) || 0;
|
||||
var maxCancel = orderQtyNum > 0 ? orderQtyNum - 1 : 0;
|
||||
|
||||
html += '<tr>';
|
||||
html += '<td style="border: 1px solid #ddd; padding: 8px; text-align: center;">' + partNo + '</td>';
|
||||
html += '<td style="border: 1px solid #ddd; padding: 8px; text-align: left;">' + partName + '</td>';
|
||||
html += '<td style="border: 1px solid #ddd; padding: 8px; text-align: right;">' + (orderQtyNum > 0 ? Number(orderQtyNum).toLocaleString() : '-') + '</td>';
|
||||
html += '<td style="border: 1px solid #ddd; padding: 8px; text-align: center;">';
|
||||
if(orderQtyNum > 0){
|
||||
html += '<input type="number" class="cancel-qty-input" data-objid="' + objid + '" data-order-qty="' + orderQtyNum + '" ';
|
||||
html += 'value="' + (cancelQty || '') + '" min="0" max="' + maxCancel + '" ';
|
||||
html += 'style="width: 80px; text-align: right; padding: 4px;" placeholder="0">';
|
||||
} else {
|
||||
html += '-';
|
||||
}
|
||||
html += '</td>';
|
||||
html += '</tr>';
|
||||
});
|
||||
|
||||
html += '</tbody></table>';
|
||||
html += '<p style="margin-top: 10px; color: #888; font-size: 12px;">※ 전체 수량 취소는 불가하며, 부분 수량만 취소 가능합니다.</p>';
|
||||
html += '</div>';
|
||||
|
||||
Swal.fire({
|
||||
title: '수주취소 수량 입력',
|
||||
html: html,
|
||||
width: '700px',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '저장',
|
||||
cancelButtonText: '닫기',
|
||||
confirmButtonColor: '#e74c3c',
|
||||
preConfirm: function(){
|
||||
var inputs = document.querySelectorAll('.cancel-qty-input');
|
||||
var itemObjIds = [];
|
||||
var cancelQtys = [];
|
||||
var orderQtys = [];
|
||||
var hasError = false;
|
||||
|
||||
inputs.forEach(function(input){
|
||||
var val = input.value.trim();
|
||||
var orderQty = parseInt(input.getAttribute('data-order-qty'));
|
||||
var cancelVal = val === '' ? 0 : parseInt(val);
|
||||
|
||||
if(cancelVal < 0){
|
||||
Swal.showValidationMessage('취소 수량은 0 이상이어야 합니다.');
|
||||
hasError = true;
|
||||
return;
|
||||
}
|
||||
if(cancelVal >= orderQty){
|
||||
Swal.showValidationMessage('취소 수량(' + cancelVal + ')은 수주수량(' + orderQty + ')보다 적어야 합니다.');
|
||||
hasError = true;
|
||||
return;
|
||||
}
|
||||
|
||||
itemObjIds.push(input.getAttribute('data-objid'));
|
||||
cancelQtys.push(cancelVal);
|
||||
orderQtys.push(orderQty);
|
||||
});
|
||||
|
||||
if(hasError) return false;
|
||||
|
||||
return { itemObjIds: itemObjIds, cancelQtys: cancelQtys, orderQtys: orderQtys };
|
||||
}
|
||||
}).then(function(result){
|
||||
if(result.isConfirmed && result.value){
|
||||
var val = result.value;
|
||||
$.ajax({
|
||||
url: "/contractMgmt/saveOrderCancelQty.do",
|
||||
type: "POST",
|
||||
data: {
|
||||
itemObjIds: val.itemObjIds.join(","),
|
||||
cancelQtys: val.cancelQtys.join(","),
|
||||
orderQtys: val.orderQtys.join(",")
|
||||
},
|
||||
dataType: "json",
|
||||
success: function(res){
|
||||
if(res.result === "true"){
|
||||
Swal.fire({ title: '저장 완료', text: res.msg, icon: 'success' });
|
||||
fn_search();
|
||||
} else {
|
||||
Swal.fire({ title: '저장 실패', text: res.msg, icon: 'error' });
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
Swal.fire("수주취소 저장 중 오류가 발생했습니다.");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(){
|
||||
Swal.fire("품목 정보 조회 중 오류가 발생했습니다.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//코드값을 받아와서 동적으로 selectbox 생성
|
||||
function optionJobGroup(code){
|
||||
var val=code;
|
||||
@@ -790,11 +945,12 @@ function openProjectFormPopUp(objId){
|
||||
<h2>
|
||||
<span>영업관리_주문서관리</span>
|
||||
</h2>
|
||||
<div class="btnArea">
|
||||
<input type="button" value="조회" class="plm_btns" id="btnSearch" name="btnSearch">
|
||||
<input type="button" value="수주등록" class="plm_btns btnRegist">
|
||||
<input type="button" value="결재상신" class="plm_btns" id="btnApproval">
|
||||
</div>
|
||||
<div class="btnArea">
|
||||
<input type="button" value="조회" class="plm_btns" id="btnSearch" name="btnSearch">
|
||||
<input type="button" value="수주등록" class="plm_btns btnRegist">
|
||||
<input type="button" value="수주취소" class="plm_btns" id="btnOrderCancel" style="background-color:#e74c3c; color:#fff;">
|
||||
<input type="button" value="결재상신" class="plm_btns" id="btnApproval">
|
||||
</div>
|
||||
</div>
|
||||
<div id="plmSearchZon">
|
||||
<!-- 검색필터: 주문유형, 발주번호, 고객사, 품번, 품명, S/N, 수주상태, 발주일(기간), 요청납기(기간) -->
|
||||
|
||||
@@ -75,6 +75,7 @@ body, html {
|
||||
<div class="header">
|
||||
<h3 style="margin: 0 0 10px 0; float: left;">구매리스트</h3>
|
||||
<div style="float: right;">
|
||||
<input type="button" class="plm_btns excelIcon excelBtn" value="Excel Download" title="Excel Download">
|
||||
<input type="button" value="견적요청서 생성" class="plm_btns" onclick="fn_createQuotationRequest();" style="margin-right: 5px; background-color: #4CAF50; border-color: #4CAF50;">
|
||||
<input type="button" value="저장" class="plm_btns" onclick="fn_save();" style="margin-right: 5px;">
|
||||
<input type="button" value="닫기" class="plm_btns" onclick="window.close();" style="margin-right: 5px;">
|
||||
@@ -565,13 +566,11 @@ function fn_initGrid() {
|
||||
title: '<span style="background-color: #FFFF00; padding: 2px 5px;">공급업체</span>',
|
||||
field: 'VENDOR_PM',
|
||||
editor: function(cell, onRendered, success, cancel, editorParams) {
|
||||
// Select2 에디터 (가공업체와 동일한 목록 사용)
|
||||
return createSelect2Editor(processingVendorList)(cell, onRendered, success, cancel, editorParams);
|
||||
},
|
||||
formatter: function(cell) {
|
||||
var value = cell.getValue();
|
||||
var value = (typeof cell.getValue === 'function') ? cell.getValue() : (cell.value || '');
|
||||
if(!value) return '';
|
||||
// processingVendorList에서 해당 값의 이름 찾기
|
||||
for(var i = 0; i < processingVendorList.length; i++) {
|
||||
if(processingVendorList[i].id == value) {
|
||||
return processingVendorList[i].text;
|
||||
@@ -686,9 +685,8 @@ function fn_initGrid() {
|
||||
return createSelect2Editor(processingVendorList)(cell, onRendered, success, cancel, editorParams);
|
||||
},
|
||||
formatter: function(cell) {
|
||||
var value = cell.getValue();
|
||||
var value = (typeof cell.getValue === 'function') ? cell.getValue() : (cell.value || '');
|
||||
if(!value) return '';
|
||||
|
||||
for(var i = 0; i < processingVendorList.length; i++) {
|
||||
if(processingVendorList[i].id == value) {
|
||||
return processingVendorList[i].text;
|
||||
@@ -783,6 +781,32 @@ function fn_initGrid() {
|
||||
return value;
|
||||
}
|
||||
},
|
||||
// 35. 소재발주일
|
||||
{
|
||||
headerHozAlign: 'center',
|
||||
hozAlign: 'center',
|
||||
width: 100,
|
||||
title: '소재발주일',
|
||||
field: 'MATERIAL_PO_DATE',
|
||||
formatter: function(cell) {
|
||||
var value = (typeof cell.getValue === 'function') ? cell.getValue() : (cell.value || '');
|
||||
if(!value) return '';
|
||||
return value.length >= 10 ? value.substring(0, 10) : value;
|
||||
}
|
||||
},
|
||||
// 36. 소재입고일
|
||||
{
|
||||
headerHozAlign: 'center',
|
||||
hozAlign: 'center',
|
||||
width: 100,
|
||||
title: '소재입고일',
|
||||
field: 'MATERIAL_RECEIPT_DATE',
|
||||
formatter: function(cell) {
|
||||
var value = (typeof cell.getValue === 'function') ? cell.getValue() : (cell.value || '');
|
||||
if(!value) return '';
|
||||
return value.length >= 10 ? value.substring(0, 10) : value;
|
||||
}
|
||||
},
|
||||
// 34. 가공 품의서작성일
|
||||
{
|
||||
headerHozAlign: 'center',
|
||||
@@ -791,14 +815,39 @@ function fn_initGrid() {
|
||||
title: '가공품의서일',
|
||||
field: 'PROCESSING_PROPOSAL_DATE',
|
||||
formatter: function(cell) {
|
||||
var value = cell.getValue();
|
||||
var value = (typeof cell.getValue === 'function') ? cell.getValue() : (cell.value || '');
|
||||
if(!value) return '';
|
||||
// YYYY-MM-DD 형식으로 표시
|
||||
if(value.length >= 10) {
|
||||
return value.substring(0, 10);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
// 37. 가공발주일
|
||||
{
|
||||
headerHozAlign: 'center',
|
||||
hozAlign: 'center',
|
||||
width: 100,
|
||||
title: '가공발주일',
|
||||
field: 'PROCESSING_PO_DATE',
|
||||
formatter: function(cell) {
|
||||
var value = (typeof cell.getValue === 'function') ? cell.getValue() : (cell.value || '');
|
||||
if(!value) return '';
|
||||
return value.length >= 10 ? value.substring(0, 10) : value;
|
||||
}
|
||||
},
|
||||
// 38. 가공입고일
|
||||
{
|
||||
headerHozAlign: 'center',
|
||||
hozAlign: 'center',
|
||||
width: 100,
|
||||
title: '가공입고일',
|
||||
field: 'PROCESSING_RECEIPT_DATE',
|
||||
formatter: function(cell) {
|
||||
var value = (typeof cell.getValue === 'function') ? cell.getValue() : (cell.value || '');
|
||||
if(!value) return '';
|
||||
return value.length >= 10 ? value.substring(0, 10) : value;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
@@ -875,8 +924,9 @@ function fn_loadFromMBom(callback) {
|
||||
url: "/salesMng/getMBomForPurchaseList.do",
|
||||
method: 'post',
|
||||
data: {
|
||||
PROJECT_MGMT_OBJID: mbomHeaderObjid, // MBOM_HEADER_OBJID를 직접 사용
|
||||
bomReportObjId: bomReportObjid
|
||||
PROJECT_MGMT_OBJID: mbomHeaderObjid,
|
||||
bomReportObjId: bomReportObjid,
|
||||
SALES_REQUEST_MASTER_OBJID: salesRequestMasterObjid
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
|
||||
@@ -91,10 +91,10 @@
|
||||
fn_bulkRegister();
|
||||
});
|
||||
|
||||
// 거래명세서 출력 버튼 (주석처리됨)
|
||||
// $("#btnTransactionStatement").click(function(){
|
||||
// fn_printTransactionStatement();
|
||||
// });
|
||||
// 거래명세서 출력 버튼
|
||||
$("#btnTransactionStatement").click(function(){
|
||||
fn_printTransactionStatement();
|
||||
});
|
||||
|
||||
// 분할출하 버튼
|
||||
$("#btnSplitShipment").click(function(){
|
||||
@@ -710,9 +710,7 @@ body {
|
||||
</h2>
|
||||
<div class="btnArea">
|
||||
<input type="button" value="조회" class="plm_btns" id="btnSearch">
|
||||
<%-- 거래명세서 버튼 주석처리
|
||||
<input type="button" value="거래명세서 생성" class="plm_btns" id="btnTransactionStatement" style="background-color: #2196F3; color: white;">
|
||||
--%>
|
||||
<input type="button" value="출하지시/판매등록" class="plm_btns" id="btnBulkRegister" style="background-color: #4CAF50; color: white;">
|
||||
<!-- <input type="button" value="분할출하" class="plm_btns" id="btnSplitShipment" style="background-color: #FF9800; color: white;"> -->
|
||||
</div>
|
||||
|
||||
@@ -3187,7 +3187,51 @@ UPDATE SET
|
||||
0 AS GRAND_TOTAL_PRICE,
|
||||
SRP.PROPOSAL_DATE,
|
||||
NULL AS PROCESSING_PROPOSAL_DATE,
|
||||
'SRP' AS DATA_SOURCE -- 데이터 소스 구분용
|
||||
-- 소재발주일: 소재품번으로 매칭
|
||||
(SELECT POM.MAIL_SEND_DATE
|
||||
FROM PURCHASE_ORDER_MASTER POM
|
||||
JOIN PURCHASE_ORDER_PART POP ON POM.OBJID = POP.PURCHASE_ORDER_MASTER_OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE COALESCE(SRP.RAW_MATERIAL_PART_NO, '') != ''
|
||||
AND POP.PART_OBJID::VARCHAR = (SELECT PM2.OBJID::VARCHAR FROM PART_MNG PM2 WHERE PM2.PART_NO = SRP.RAW_MATERIAL_PART_NO LIMIT 1)
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = SRP.SALES_REQUEST_MASTER_OBJID)
|
||||
AND POM.MAIL_SEND_DATE IS NOT NULL
|
||||
ORDER BY POM.MAIL_SEND_DATE DESC
|
||||
LIMIT 1) AS MATERIAL_PO_DATE,
|
||||
-- 소재입고일
|
||||
(SELECT SUBSTRING(AP.RECEIPT_DATE, 1, 10)
|
||||
FROM ARRIVAL_PLAN AP
|
||||
JOIN PURCHASE_ORDER_PART POP ON AP.ORDER_PART_OBJID = POP.OBJID
|
||||
JOIN PURCHASE_ORDER_MASTER POM ON POP.PURCHASE_ORDER_MASTER_OBJID = POM.OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE COALESCE(SRP.RAW_MATERIAL_PART_NO, '') != ''
|
||||
AND POP.PART_OBJID::VARCHAR = (SELECT PM2.OBJID::VARCHAR FROM PART_MNG PM2 WHERE PM2.PART_NO = SRP.RAW_MATERIAL_PART_NO LIMIT 1)
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = SRP.SALES_REQUEST_MASTER_OBJID)
|
||||
AND AP.RECEIPT_DATE IS NOT NULL AND AP.RECEIPT_DATE != ''
|
||||
ORDER BY AP.RECEIPT_DATE DESC
|
||||
LIMIT 1) AS MATERIAL_RECEIPT_DATE,
|
||||
-- 가공발주일: 부품 PART_OBJID로 직접 매칭
|
||||
(SELECT POM.MAIL_SEND_DATE
|
||||
FROM PURCHASE_ORDER_MASTER POM
|
||||
JOIN PURCHASE_ORDER_PART POP ON POM.OBJID = POP.PURCHASE_ORDER_MASTER_OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE POP.PART_OBJID::VARCHAR = SRP.PART_OBJID::VARCHAR
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = SRP.SALES_REQUEST_MASTER_OBJID)
|
||||
AND POM.MAIL_SEND_DATE IS NOT NULL
|
||||
ORDER BY POM.MAIL_SEND_DATE DESC
|
||||
LIMIT 1) AS PROCESSING_PO_DATE,
|
||||
-- 가공입고일
|
||||
(SELECT SUBSTRING(AP.RECEIPT_DATE, 1, 10)
|
||||
FROM ARRIVAL_PLAN AP
|
||||
JOIN PURCHASE_ORDER_PART POP ON AP.ORDER_PART_OBJID = POP.OBJID
|
||||
JOIN PURCHASE_ORDER_MASTER POM ON POP.PURCHASE_ORDER_MASTER_OBJID = POM.OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE POP.PART_OBJID::VARCHAR = SRP.PART_OBJID::VARCHAR
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = SRP.SALES_REQUEST_MASTER_OBJID)
|
||||
AND AP.RECEIPT_DATE IS NOT NULL AND AP.RECEIPT_DATE != ''
|
||||
ORDER BY AP.RECEIPT_DATE DESC
|
||||
LIMIT 1) AS PROCESSING_RECEIPT_DATE,
|
||||
'SRP' AS DATA_SOURCE
|
||||
FROM
|
||||
SALES_REQUEST_PART SRP
|
||||
LEFT JOIN PART_MNG PM ON SRP.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
|
||||
@@ -3519,6 +3563,58 @@ SELECT
|
||||
G.PROCESSING_UNIT_PRICE,
|
||||
G.PROCESSING_TOTAL_PRICE,
|
||||
G.GRAND_TOTAL_PRICE,
|
||||
<if test="SALES_REQUEST_MASTER_OBJID != null and !''.equals(SALES_REQUEST_MASTER_OBJID)">
|
||||
-- 소재발주일: 소재품번(RAW_MATERIAL_PART_NO)으로 PART_MNG OBJID 조회 후 매칭
|
||||
(SELECT POM.MAIL_SEND_DATE
|
||||
FROM PURCHASE_ORDER_MASTER POM
|
||||
JOIN PURCHASE_ORDER_PART POP ON POM.OBJID = POP.PURCHASE_ORDER_MASTER_OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE COALESCE(G.RAW_MATERIAL_PART_NO, '') != ''
|
||||
AND POP.PART_OBJID::VARCHAR = (SELECT PM2.OBJID::VARCHAR FROM PART_MNG PM2 WHERE PM2.PART_NO = G.RAW_MATERIAL_PART_NO LIMIT 1)
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = #{SALES_REQUEST_MASTER_OBJID})
|
||||
AND POM.MAIL_SEND_DATE IS NOT NULL
|
||||
ORDER BY POM.MAIL_SEND_DATE DESC
|
||||
LIMIT 1) AS MATERIAL_PO_DATE,
|
||||
-- 소재입고일
|
||||
(SELECT SUBSTRING(AP.RECEIPT_DATE, 1, 10)
|
||||
FROM ARRIVAL_PLAN AP
|
||||
JOIN PURCHASE_ORDER_PART POP ON AP.ORDER_PART_OBJID = POP.OBJID
|
||||
JOIN PURCHASE_ORDER_MASTER POM ON POP.PURCHASE_ORDER_MASTER_OBJID = POM.OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE COALESCE(G.RAW_MATERIAL_PART_NO, '') != ''
|
||||
AND POP.PART_OBJID::VARCHAR = (SELECT PM2.OBJID::VARCHAR FROM PART_MNG PM2 WHERE PM2.PART_NO = G.RAW_MATERIAL_PART_NO LIMIT 1)
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = #{SALES_REQUEST_MASTER_OBJID})
|
||||
AND AP.RECEIPT_DATE IS NOT NULL AND AP.RECEIPT_DATE != ''
|
||||
ORDER BY AP.RECEIPT_DATE DESC
|
||||
LIMIT 1) AS MATERIAL_RECEIPT_DATE,
|
||||
-- 가공발주일: 부품 PART_OBJID로 직접 매칭
|
||||
(SELECT POM.MAIL_SEND_DATE
|
||||
FROM PURCHASE_ORDER_MASTER POM
|
||||
JOIN PURCHASE_ORDER_PART POP ON POM.OBJID = POP.PURCHASE_ORDER_MASTER_OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE POP.PART_OBJID::VARCHAR = G.PART_OBJID::VARCHAR
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = #{SALES_REQUEST_MASTER_OBJID})
|
||||
AND POM.MAIL_SEND_DATE IS NOT NULL
|
||||
ORDER BY POM.MAIL_SEND_DATE DESC
|
||||
LIMIT 1) AS PROCESSING_PO_DATE,
|
||||
-- 가공입고일
|
||||
(SELECT SUBSTRING(AP.RECEIPT_DATE, 1, 10)
|
||||
FROM ARRIVAL_PLAN AP
|
||||
JOIN PURCHASE_ORDER_PART POP ON AP.ORDER_PART_OBJID = POP.OBJID
|
||||
JOIN PURCHASE_ORDER_MASTER POM ON POP.PURCHASE_ORDER_MASTER_OBJID = POM.OBJID
|
||||
JOIN SALES_REQUEST_MASTER SRM_PO ON POM.SALES_REQUEST_OBJID = SRM_PO.OBJID
|
||||
WHERE POP.PART_OBJID::VARCHAR = G.PART_OBJID::VARCHAR
|
||||
AND SRM_PO.PROJECT_NO = (SELECT PROJECT_NO FROM SALES_REQUEST_MASTER WHERE OBJID = #{SALES_REQUEST_MASTER_OBJID})
|
||||
AND AP.RECEIPT_DATE IS NOT NULL AND AP.RECEIPT_DATE != ''
|
||||
ORDER BY AP.RECEIPT_DATE DESC
|
||||
LIMIT 1) AS PROCESSING_RECEIPT_DATE,
|
||||
</if>
|
||||
<if test="SALES_REQUEST_MASTER_OBJID == null or ''.equals(SALES_REQUEST_MASTER_OBJID)">
|
||||
NULL AS MATERIAL_PO_DATE,
|
||||
NULL AS MATERIAL_RECEIPT_DATE,
|
||||
NULL AS PROCESSING_PO_DATE,
|
||||
NULL AS PROCESSING_RECEIPT_DATE,
|
||||
</if>
|
||||
'MBOM' AS DATA_SOURCE
|
||||
FROM GROUPED_BOM G
|
||||
LEFT JOIN PART_MNG P ON P.OBJID::VARCHAR = G.PART_OBJID::VARCHAR
|
||||
|
||||
@@ -2853,6 +2853,25 @@ public class ContractMgmtController {
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수주취소 수량 저장
|
||||
*/
|
||||
@ResponseBody
|
||||
@RequestMapping(value="/contractMgmt/saveOrderCancelQty.do", method=RequestMethod.POST)
|
||||
public Map saveOrderCancelQty(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
|
||||
Map resultMap = new HashMap();
|
||||
|
||||
try {
|
||||
resultMap = contractMgmtService.saveOrderCancelQty(request, paramMap);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
resultMap.put("result", "false");
|
||||
resultMap.put("msg", "수주취소 저장 중 오류가 발생했습니다.");
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@RequestMapping("/contractMgmt/FileRegistPopup.do")
|
||||
public String FileRegistPopup(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
|
||||
request.setAttribute("docType", CommonUtils.checkNull(paramMap.get("docType")));
|
||||
|
||||
@@ -717,6 +717,16 @@
|
||||
AND ORDER_QUANTITY != ''
|
||||
AND ORDER_QUANTITY != '0'
|
||||
) AS HAS_ORDER_DATA
|
||||
-- 수주취소 수량 합계
|
||||
,(
|
||||
SELECT COALESCE(SUM(CAST(NULLIF(CANCEL_QTY, '') AS NUMERIC)), 0)
|
||||
FROM CONTRACT_ITEM
|
||||
WHERE CONTRACT_OBJID = T.OBJID
|
||||
AND STATUS = 'ACTIVE'
|
||||
AND CANCEL_QTY IS NOT NULL
|
||||
AND CANCEL_QTY != ''
|
||||
AND CANCEL_QTY != '0'
|
||||
) AS CANCEL_QTY_SUM
|
||||
FROM
|
||||
CONTRACT_MGMT AS T
|
||||
LEFT OUTER JOIN
|
||||
@@ -5092,7 +5102,8 @@ WHERE
|
||||
CI.ORDER_UNIT_PRICE,
|
||||
CI.ORDER_SUPPLY_PRICE,
|
||||
CI.ORDER_VAT,
|
||||
CI.ORDER_TOTAL_AMOUNT
|
||||
CI.ORDER_TOTAL_AMOUNT,
|
||||
CI.CANCEL_QTY
|
||||
FROM
|
||||
CONTRACT_ITEM CI
|
||||
LEFT JOIN PART_MNG PM ON CI.PART_OBJID = PM.OBJID
|
||||
@@ -5117,7 +5128,8 @@ WHERE
|
||||
CI.ORDER_UNIT_PRICE,
|
||||
CI.ORDER_SUPPLY_PRICE,
|
||||
CI.ORDER_VAT,
|
||||
CI.ORDER_TOTAL_AMOUNT
|
||||
CI.ORDER_TOTAL_AMOUNT,
|
||||
CI.CANCEL_QTY
|
||||
ORDER BY CI.SEQ
|
||||
</select>
|
||||
|
||||
@@ -5133,6 +5145,16 @@ WHERE
|
||||
WHERE OBJID = #{contractItemObjId}
|
||||
</update>
|
||||
|
||||
<!-- 수주취소 수량 업데이트 -->
|
||||
<update id="updateContractItemCancelQty" parameterType="map">
|
||||
UPDATE CONTRACT_ITEM
|
||||
SET
|
||||
CANCEL_QTY = #{cancelQty},
|
||||
CHGDATE = NOW(),
|
||||
CHG_USER_ID = #{userId}
|
||||
WHERE OBJID = #{itemObjId}
|
||||
</update>
|
||||
|
||||
<!-- ====================================
|
||||
품목 관리 쿼리
|
||||
==================================== -->
|
||||
|
||||
@@ -3865,4 +3865,89 @@ private String encodeImageToBase64(String imagePath) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 수주취소 수량 저장
|
||||
* 품목별로 부분 취소 수량을 업데이트한다. (전체 취소 불가, 부분만 가능)
|
||||
*/
|
||||
public Map<String, Object> saveOrderCancelQty(HttpServletRequest request, Map<String, Object> paramMap) {
|
||||
Map<String, Object> resultMap = new HashMap<String, Object>();
|
||||
SqlSession sqlSession = null;
|
||||
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
PersonBean person = (PersonBean) session.getAttribute(Constants.PERSON_BEAN);
|
||||
String userId = person.getUserId();
|
||||
|
||||
String itemObjIdsStr = CommonUtils.checkNull(paramMap.get("itemObjIds"));
|
||||
String cancelQtysStr = CommonUtils.checkNull(paramMap.get("cancelQtys"));
|
||||
String orderQtysStr = CommonUtils.checkNull(paramMap.get("orderQtys"));
|
||||
|
||||
if ("".equals(itemObjIdsStr) || "".equals(cancelQtysStr)) {
|
||||
resultMap.put("result", "false");
|
||||
resultMap.put("msg", "취소 수량 정보가 없습니다.");
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
String[] itemObjIds = itemObjIdsStr.split(",");
|
||||
String[] cancelQtys = cancelQtysStr.split(",");
|
||||
String[] orderQtys = orderQtysStr.split(",");
|
||||
|
||||
for (int i = 0; i < itemObjIds.length; i++) {
|
||||
String cancelQty = cancelQtys[i].trim();
|
||||
String orderQty = orderQtys[i].trim();
|
||||
|
||||
// 빈 값이면 스킵
|
||||
if ("".equals(cancelQty) || "0".equals(cancelQty)) {
|
||||
// 취소수량 0이면 초기화
|
||||
Map<String, Object> updateParam = new HashMap<String, Object>();
|
||||
updateParam.put("itemObjId", itemObjIds[i].trim());
|
||||
updateParam.put("cancelQty", "");
|
||||
updateParam.put("userId", userId);
|
||||
sqlSession.update("contractMgmt.updateContractItemCancelQty", updateParam);
|
||||
continue;
|
||||
}
|
||||
|
||||
int cancelQtyInt = Integer.parseInt(cancelQty);
|
||||
int orderQtyInt = Integer.parseInt(orderQty);
|
||||
|
||||
// 전체 수량 취소 불가 (부분만 가능)
|
||||
if (cancelQtyInt >= orderQtyInt) {
|
||||
resultMap.put("result", "false");
|
||||
resultMap.put("msg", "수주취소 수량은 수주수량(" + orderQtyInt + ")보다 적어야 합니다.");
|
||||
sqlSession.rollback();
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
if (cancelQtyInt < 0) {
|
||||
resultMap.put("result", "false");
|
||||
resultMap.put("msg", "수주취소 수량은 0 이상이어야 합니다.");
|
||||
sqlSession.rollback();
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
Map<String, Object> updateParam = new HashMap<String, Object>();
|
||||
updateParam.put("itemObjId", itemObjIds[i].trim());
|
||||
updateParam.put("cancelQty", cancelQty);
|
||||
updateParam.put("userId", userId);
|
||||
sqlSession.update("contractMgmt.updateContractItemCancelQty", updateParam);
|
||||
}
|
||||
|
||||
sqlSession.commit();
|
||||
resultMap.put("result", "true");
|
||||
resultMap.put("msg", "수주취소 수량이 저장되었습니다.");
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (sqlSession != null) sqlSession.rollback();
|
||||
resultMap.put("result", "false");
|
||||
resultMap.put("msg", "수주취소 저장 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
if (sqlSession != null) sqlSession.close();
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2168,8 +2168,8 @@ public class ApprovalService {
|
||||
private String buildOrderContentsHtml(Map orderInfo, List<Map> itemList){
|
||||
StringBuilder html = new StringBuilder();
|
||||
|
||||
String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO"));
|
||||
String orderDate = CommonUtils.checkNull(orderInfo.get("ORDER_DATE"));
|
||||
String poNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("PO_NO")));
|
||||
String clientNm = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_NM")));
|
||||
String clientBusRegNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_REG_NO")));
|
||||
String clientCeoNm = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_CEO_NM")));
|
||||
@@ -2183,63 +2183,79 @@ public class ApprovalService {
|
||||
String vat = CommonUtils.checkNull(orderInfo.get("ORDER_VAT"));
|
||||
String totalAmount = CommonUtils.checkNull(orderInfo.get("ORDER_TOTAL_AMOUNT"));
|
||||
String vatNote = escapeHtml(CommonUtils.checkNull(orderInfo.get("VAT_NOTE")));
|
||||
String regDatetime = escapeHtml(CommonUtils.checkNull(orderInfo.get("REG_DATETIME")));
|
||||
|
||||
final String TH = "style='border:1px solid #999; padding:4px 8px; background-color:#f5f5f5; text-align:center; font-weight:bold; font-size:12px;'";
|
||||
final String TD = "style='border:1px solid #999; padding:4px 8px; font-size:12px;'";
|
||||
final String TD_C = "style='border:1px solid #999; padding:4px 8px; font-size:12px; text-align:center;'";
|
||||
final String TD_R = "style='border:1px solid #999; padding:4px 8px; font-size:12px; text-align:right;'";
|
||||
final String S = "border:1px solid #000; padding:2px 4px; font-size:11px; vertical-align:middle;";
|
||||
final String LBL = S + " text-align:center; font-weight:bold; background-color:#e8faff;";
|
||||
final String VL = LBL + " writing-mode:vertical-rl; letter-spacing:5px; font-size:12px;";
|
||||
|
||||
html.append("<div style='font-family:맑은 고딕; max-width:800px; margin:0 auto;'>");
|
||||
html.append("<h2 style='text-align:center; letter-spacing:15px;'>주 문 서</h2>");
|
||||
html.append("<div style='font-family:맑은 고딕,Malgun Gothic,sans-serif; max-width:860px; margin:0 auto;'>");
|
||||
html.append("<h2 style='text-align:center; letter-spacing:25px; border-bottom:2px solid #000; padding-bottom:8px;'>주 문 서</h2>");
|
||||
html.append("<p style='font-size:11px; margin:2px 0;'>주문일자 : ").append(escapeHtml(orderDate)).append("</p>");
|
||||
html.append("<p style='font-size:11px; margin:2px 0;'>증빙번호 : ").append(poNo).append("</p>");
|
||||
|
||||
// 헤더
|
||||
String poNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("PO_NO")));
|
||||
html.append("<p style='font-size:12px;'>주문일자 : ").append(escapeHtml(orderDate)).append("</p>");
|
||||
html.append("<p style='font-size:12px;'>증빙번호 : ").append(poNo).append("</p>");
|
||||
|
||||
// 공급받는자/공급자 테이블
|
||||
html.append("<table style='width:100%; border-collapse:collapse; margin-bottom:5px;'>");
|
||||
html.append("<tr><td rowspan='4' " + TH + " style='width:25px; writing-mode:vertical-rl;'>공급받는자</td>");
|
||||
html.append("<td " + TH + ">등록번호</td><td " + TD + " colspan='2'>").append(clientBusRegNo).append("</td>");
|
||||
html.append("<td rowspan='4' " + TH + " style='width:25px; writing-mode:vertical-rl;'>공급자</td>");
|
||||
html.append("<td " + TH + ">등록번호</td><td " + TD + " colspan='2'>314-81-75146</td></tr>");
|
||||
|
||||
html.append("<tr><td " + TH + ">상호</td><td " + TD + ">").append(clientNm).append("</td>");
|
||||
html.append("<td " + TH + " style='width:35px;'>성명</td><td " + TD + ">").append(clientCeoNm).append("</td>");
|
||||
html.append("<td " + TH + ">상호</td><td " + TD + ">주식회사알피에스본사</td>");
|
||||
html.append("<td " + TH + " style='width:35px;'>성명</td><td " + TD + ">이동헌</td></tr>");
|
||||
|
||||
html.append("<tr><td " + TH + ">주소</td><td " + TD + " colspan='2'>").append(clientAddr).append("</td>");
|
||||
html.append("<td " + TH + ">주소</td><td " + TD + " colspan='2'>대전광역시 유성구 국제과학10로 8(둔곡동)</td></tr>");
|
||||
|
||||
html.append("<tr><td " + TH + ">업태</td><td " + TD + ">").append(clientBusType).append("</td>");
|
||||
html.append("<td " + TH + " style='width:35px;'>종목</td><td " + TD + ">").append(clientBusItem).append("</td>");
|
||||
html.append("<td " + TH + ">업태</td><td " + TD + ">제조업</td>");
|
||||
html.append("<td " + TH + " style='width:35px;'>종목</td><td " + TD + ">금속절삭가공기계,반도체제조용기계</td></tr>");
|
||||
html.append("</table>");
|
||||
|
||||
// 납품처/담당자
|
||||
html.append("<table style='width:100%; border-collapse:collapse; margin-bottom:5px;'>");
|
||||
html.append("<tr><td " + TH + ">납품처</td><td " + TD + ">").append(clientNm).append("</td>");
|
||||
html.append("<td " + TH + ">전화번호</td><td " + TD + ">").append(clientTelNo).append("</td>");
|
||||
html.append("<td " + TH + ">팩스번호</td><td " + TD + ">").append(clientFaxNo).append("</td></tr>");
|
||||
html.append("<tr><td " + TH + ">주소</td><td " + TD + ">").append(clientAddr).append("</td>");
|
||||
html.append("<td " + TH + ">담당자</td><td " + TD + ">").append(writerName).append("</td>");
|
||||
html.append("<td " + TH + ">C.P.번호</td><td " + TD + "></td></tr>");
|
||||
html.append("</table>");
|
||||
|
||||
// 품목 테이블
|
||||
html.append("<table style='width:100%; border-collapse:collapse;'>");
|
||||
// 공급받는자 / 공급자 (10컬럼: 세로3% + 라벨8% + 값auto + 라벨6% + 값9% × 2세트)
|
||||
html.append("<table style='width:100%; border-collapse:collapse; table-layout:fixed; margin-top:2px;'>");
|
||||
html.append("<colgroup>");
|
||||
html.append("<col style='width:3%;'><col style='width:8%;'><col style='width:20%;'><col style='width:6%;'><col style='width:9%;'>");
|
||||
html.append("<col style='width:3%;'><col style='width:8%;'><col style='width:20%;'><col style='width:6%;'><col style='width:12%;'>");
|
||||
html.append("</colgroup>");
|
||||
// row1: 등록번호
|
||||
html.append("<tr>");
|
||||
html.append("<th " + TH + " style='width:30px;'>No.</th>");
|
||||
html.append("<th " + TH + " style='width:90px;'>품번</th>");
|
||||
html.append("<th " + TH + ">품명</th>");
|
||||
html.append("<th " + TH + ">규격</th>");
|
||||
html.append("<th " + TH + " style='width:40px;'>단위</th>");
|
||||
html.append("<th " + TH + " style='width:75px;'>납기일</th>");
|
||||
html.append("<th " + TH + " style='width:50px;'>수량</th>");
|
||||
html.append("<th " + TH + " style='width:70px;'>단가</th>");
|
||||
html.append("<th " + TH + " style='width:80px;'>금액</th>");
|
||||
html.append("<td rowspan='4' style='").append(VL).append("'>공급받는자</td>");
|
||||
html.append("<td style='").append(LBL).append("'>등록번호</td>");
|
||||
html.append("<td colspan='3' style='").append(S).append("'>").append(clientBusRegNo).append("</td>");
|
||||
html.append("<td rowspan='4' style='").append(VL).append("'>공 급 자</td>");
|
||||
html.append("<td style='").append(LBL).append("'>등록번호</td>");
|
||||
html.append("<td colspan='3' style='").append(S).append("'>314-81-75146</td>");
|
||||
html.append("</tr>");
|
||||
// row2: 상호/성명
|
||||
html.append("<tr>");
|
||||
html.append("<td style='").append(LBL).append("'>상 호</td><td style='").append(S).append("'>").append(clientNm).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>성명</td><td style='").append(S).append("'>").append(clientCeoNm).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>상 호</td><td style='").append(S).append("'>주식회사알피에스본사</td>");
|
||||
html.append("<td style='").append(LBL).append("'>성명</td><td style='").append(S).append("'>이동헌</td>");
|
||||
html.append("</tr>");
|
||||
// row3: 주소
|
||||
html.append("<tr>");
|
||||
html.append("<td style='").append(LBL).append("'>주 소</td><td colspan='3' style='").append(S).append("'>").append(clientAddr).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>주 소</td><td colspan='3' style='").append(S).append("'>대전광역시 유성구 국제과학10로 8(둔곡동)</td>");
|
||||
html.append("</tr>");
|
||||
// row4: 업태/종목
|
||||
html.append("<tr>");
|
||||
html.append("<td style='").append(LBL).append("'>업 태</td><td style='").append(S).append("'>").append(clientBusType).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>종목</td><td style='").append(S).append("'>").append(clientBusItem).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>업 태</td><td style='").append(S).append("'>제조업</td>");
|
||||
html.append("<td style='").append(LBL).append("'>종목</td><td style='").append(S).append(" font-size:9px;'>금속절삭가공기계,반도체제조용기계</td>");
|
||||
html.append("</tr></table>");
|
||||
|
||||
// 납품처 / 담당자 (6컬럼)
|
||||
html.append("<table style='width:100%; border-collapse:collapse; table-layout:fixed; margin-top:-1px;'>");
|
||||
html.append("<colgroup><col style='width:9%;'><col><col style='width:9%;'><col style='width:16%;'><col style='width:9%;'><col style='width:16%;'></colgroup>");
|
||||
html.append("<tr>");
|
||||
html.append("<td style='").append(LBL).append("'>납 품 처</td><td style='").append(S).append("'>").append(clientNm).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>전화번호</td><td style='").append(S).append("'>").append(clientTelNo).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>팩스번호</td><td style='").append(S).append("'>").append(clientFaxNo).append("</td>");
|
||||
html.append("</tr><tr>");
|
||||
html.append("<td style='").append(LBL).append("'>주 소</td><td style='").append(S).append("'>").append(clientAddr).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>담 당 자</td><td style='").append(S).append("'>").append(writerName).append("</td>");
|
||||
html.append("<td style='").append(LBL).append("'>C.P.번호</td><td style='").append(S).append("'></td>");
|
||||
html.append("</tr></table>");
|
||||
|
||||
// 품목 테이블 (9컬럼)
|
||||
html.append("<table style='width:100%; border-collapse:collapse; table-layout:fixed; margin-top:-1px;'>");
|
||||
html.append("<colgroup><col style='width:4%;'><col style='width:11%;'><col style='width:20%;'><col style='width:18%;'>");
|
||||
html.append("<col style='width:5%;'><col style='width:10%;'><col style='width:6%;'><col style='width:10%;'><col style='width:10%;'></colgroup>");
|
||||
html.append("<tr>");
|
||||
html.append("<th style='").append(LBL).append("'>No.</th>");
|
||||
html.append("<th style='").append(LBL).append("'>품번</th>");
|
||||
html.append("<th style='").append(LBL).append("'>품명</th>");
|
||||
html.append("<th style='").append(LBL).append("'>규격</th>");
|
||||
html.append("<th style='").append(LBL).append("'>단위</th>");
|
||||
html.append("<th style='").append(LBL).append("'>납기일</th>");
|
||||
html.append("<th style='").append(LBL).append("'>수량</th>");
|
||||
html.append("<th style='").append(LBL).append("'>단가</th>");
|
||||
html.append("<th style='").append(LBL).append("'>금액</th>");
|
||||
html.append("</tr>");
|
||||
|
||||
int totalQty = 0;
|
||||
@@ -2253,40 +2269,42 @@ public class ApprovalService {
|
||||
String itemSupply = CommonUtils.checkNull(item.get("ORDER_SUPPLY_PRICE"));
|
||||
|
||||
html.append("<tr>");
|
||||
html.append("<td " + TD_C + ">").append(i + 1).append("</td>");
|
||||
html.append("<td " + TD_C + ">").append(escapeHtml(CommonUtils.checkNull(item.get("PART_NO")))).append("</td>");
|
||||
html.append("<td " + TD + ">").append(escapeHtml(CommonUtils.checkNull(item.get("PART_NAME")))).append("</td>");
|
||||
html.append("<td " + TD + ">").append(escapeHtml(CommonUtils.checkNull(item.get("SPEC")))).append("</td>");
|
||||
html.append("<td " + TD_C + ">").append(escapeHtml(CommonUtils.checkNull(item.get("UNIT_NAME")))).append("</td>");
|
||||
html.append("<td " + TD_C + ">").append(escapeHtml(CommonUtils.checkNull(item.get("DUE_DATE")))).append("</td>");
|
||||
html.append("<td " + TD_R + ">").append(formatNumber(qty)).append("</td>");
|
||||
html.append("<td " + TD_R + ">").append(formatNumber(unitPrice)).append("</td>");
|
||||
html.append("<td " + TD_R + ">").append(formatNumber(itemSupply)).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:center;'>").append(i + 1).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:center;'>").append(escapeHtml(CommonUtils.checkNull(item.get("PART_NO")))).append("</td>");
|
||||
html.append("<td style='").append(S).append("'>").append(escapeHtml(CommonUtils.checkNull(item.get("PART_NAME")))).append("</td>");
|
||||
html.append("<td style='").append(S).append("'>").append(escapeHtml(CommonUtils.checkNull(item.get("SPEC")))).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:center;'>").append(escapeHtml(CommonUtils.checkNull(item.get("UNIT_NAME")))).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:center;'>").append(escapeHtml(CommonUtils.checkNull(item.get("DUE_DATE")))).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:right;'>").append(formatNumber(qty)).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:right;'>").append(formatNumber(unitPrice)).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:right;'>").append(formatNumber(itemSupply)).append("</td>");
|
||||
html.append("</tr>");
|
||||
}
|
||||
}
|
||||
|
||||
// 합계
|
||||
html.append("<tr style='background-color:#ffffcc;'>");
|
||||
html.append("<td " + TD_C + " colspan='6' style='font-weight:bold;'>합 계</td>");
|
||||
html.append("<td " + TD_R + " style='font-weight:bold;'>").append(formatNumber(totalQty)).append("</td>");
|
||||
html.append("<td " + TD_R + "></td>");
|
||||
html.append("<td " + TD_R + " style='font-weight:bold;'>").append(formatNumber(supplyPrice)).append("</td>");
|
||||
// 합계행
|
||||
html.append("<tr><td colspan='9' style='").append(S).append(" text-align:center; background-color:#ffffcc; font-weight:bold; letter-spacing:8px;'>합 계</td></tr>");
|
||||
html.append("<tr>");
|
||||
html.append("<td colspan='6' style='").append(S).append(" text-align:center; font-weight:bold;'></td>");
|
||||
html.append("<td style='").append(S).append(" text-align:right; font-weight:bold;'>").append(formatNumber(totalQty)).append("</td>");
|
||||
html.append("<td style='").append(S).append(" text-align:right;'></td>");
|
||||
html.append("<td style='").append(S).append(" text-align:right; font-weight:bold;'>").append(formatNumber(supplyPrice)).append("</td>");
|
||||
html.append("</tr></table>");
|
||||
|
||||
// 비고(합계 요약)
|
||||
html.append("<table style='width:100%; border-collapse:collapse;'>");
|
||||
html.append("<tr><td rowspan='3' " + TH + " style='width:40px; writing-mode:vertical-rl; letter-spacing:8px; font-size:13px;'>비 고</td>");
|
||||
html.append("<td rowspan='3' " + TD + "></td>");
|
||||
html.append("<td " + TH + " style='width:120px; letter-spacing:2px;'>공 급 가 액 합 계</td><td " + TD_R + " style='width:150px;'>").append(formatNumber(supplyPrice)).append("</td></tr>");
|
||||
html.append("<tr><td " + TH + " style='letter-spacing:2px;'>부 가 가 치 세</td><td " + TD_R + ">").append(formatNumber(vat)).append("</td></tr>");
|
||||
html.append("<tr><td " + TH + " style='letter-spacing:5px;'>총 계</td><td " + TD_R + " style='font-weight:bold;'>").append(formatNumber(totalAmount)).append("</td></tr>");
|
||||
// 비고(합계 요약) - 4컬럼
|
||||
html.append("<table style='width:100%; border-collapse:collapse; table-layout:fixed; margin-top:-1px;'>");
|
||||
html.append("<colgroup><col style='width:5%;'><col><col style='width:15%;'><col style='width:19%;'></colgroup>");
|
||||
html.append("<tr><td rowspan='3' style='").append(VL).append(" letter-spacing:8px; font-size:13px;'>비 고</td>");
|
||||
html.append("<td rowspan='3' style='").append(S).append("'></td>");
|
||||
html.append("<td style='").append(LBL).append(" letter-spacing:2px;'>공 급 가 액 합 계</td><td style='").append(S).append(" text-align:right;'>").append(formatNumber(supplyPrice)).append("</td></tr>");
|
||||
html.append("<tr><td style='").append(LBL).append(" letter-spacing:2px;'>부 가 가 치 세</td><td style='").append(S).append(" text-align:right;'>").append(formatNumber(vat)).append("</td></tr>");
|
||||
html.append("<tr><td style='").append(LBL).append(" letter-spacing:5px;'>총 계</td><td style='").append(S).append(" text-align:right; font-weight:bold;'>").append(formatNumber(totalAmount)).append("</td></tr>");
|
||||
html.append("</table>");
|
||||
// 하단 부가세 구분 + 날짜
|
||||
html.append("<div style='display:flex; justify-content:space-between; padding:3px 5px; font-size:11px; border:1px solid #999; border-top:none;'>");
|
||||
html.append("<span>").append(vatNote).append("</span>");
|
||||
html.append("<span>").append(escapeHtml(CommonUtils.checkNull(orderInfo.get("REG_DATETIME")))).append("</span>");
|
||||
html.append("</div>");
|
||||
html.append("<table style='width:100%; border-collapse:collapse; margin-top:-1px;'><tr>");
|
||||
html.append("<td style='").append(S).append(" border-top:none;'>").append(vatNote).append("</td>");
|
||||
html.append("<td style='").append(S).append(" border-top:none; text-align:right;'>").append(regDatetime).append("</td>");
|
||||
html.append("</tr></table>");
|
||||
|
||||
html.append("</div>");
|
||||
|
||||
@@ -2301,6 +2319,7 @@ public class ApprovalService {
|
||||
|
||||
String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO"));
|
||||
String orderDate = CommonUtils.checkNull(orderInfo.get("ORDER_DATE"));
|
||||
String poNo = CommonUtils.checkNull(orderInfo.get("PO_NO"));
|
||||
String clientNm = CommonUtils.checkNull(orderInfo.get("CLIENT_NM"));
|
||||
String clientBusRegNo = CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_REG_NO"));
|
||||
String clientCeoNm = CommonUtils.checkNull(orderInfo.get("CLIENT_CEO_NM"));
|
||||
@@ -2319,55 +2338,54 @@ public class ApprovalService {
|
||||
html.append("<!DOCTYPE html><html><head><meta charset='UTF-8'>");
|
||||
html.append("<title>주문서 - ").append(contractNo).append("</title>");
|
||||
html.append("<style>");
|
||||
html.append("body { font-family: '맑은 고딕', sans-serif; font-size: 12px; margin: 20px 40px; }");
|
||||
html.append(".title { text-align: center; font-size: 26px; font-weight: bold; letter-spacing: 18px; margin-bottom: 10px; }");
|
||||
html.append(".header { font-size: 12px; margin-bottom: 8px; }");
|
||||
html.append("table { width: 100%; border-collapse: collapse; margin-bottom: 5px; }");
|
||||
html.append("th, td { border: 1px solid #000; padding: 3px 6px; font-size: 11px; }");
|
||||
html.append("th { background-color: #f0f0f0; text-align: center; font-weight: bold; }");
|
||||
html.append(".center { text-align: center; }");
|
||||
html.append(".right { text-align: right; }");
|
||||
html.append(".total-row td { background-color: #ffffcc; font-weight: bold; }");
|
||||
html.append(".vl { writing-mode: vertical-rl; letter-spacing: 3px; width: 25px; text-align: center; font-weight: bold; background-color: #f0f0f0; }");
|
||||
html.append("body { font-family:'맑은 고딕',sans-serif; font-size:12px; margin:15px 20px; }");
|
||||
html.append("table { width:100%; border-collapse:collapse; }");
|
||||
html.append("td,th { border:1px solid #000; padding:2px 4px; font-size:11px; vertical-align:middle; word-break:break-all; }");
|
||||
html.append(".lbl { text-align:center; font-weight:bold; background-color:#e8faff; }");
|
||||
html.append(".vl { text-align:center; font-weight:bold; background-color:#e8faff; writing-mode:vertical-rl; letter-spacing:5px; font-size:12px; }");
|
||||
html.append(".tc { text-align:center; } .tr { text-align:right; }");
|
||||
html.append("</style></head><body>");
|
||||
|
||||
html.append("<div class='title'>주 문 서</div>");
|
||||
String poNo = CommonUtils.checkNull(orderInfo.get("PO_NO"));
|
||||
html.append("<div class='header'>주문일자 : ").append(orderDate).append("</div>");
|
||||
html.append("<div class='header'>증빙번호 : ").append(poNo).append("</div>");
|
||||
html.append("<div style='max-width:860px; margin:0 auto;'>");
|
||||
html.append("<div style='text-align:center; font-size:24px; font-weight:bold; letter-spacing:25px; padding:10px 0 8px 0; border-bottom:2px solid #000; margin-bottom:3px;'>주 문 서</div>");
|
||||
html.append("<div style='font-size:11px; padding:2px 0;'>주문일자 : ").append(orderDate).append("</div>");
|
||||
html.append("<div style='font-size:11px; padding:2px 0;'>증빙번호 : ").append(poNo).append("</div>");
|
||||
|
||||
// 공급받는자/공급자
|
||||
html.append("<table>");
|
||||
html.append("<tr><td class='vl' rowspan='4'>공<br/>급<br/>받<br/>는<br/>자</td>");
|
||||
html.append("<th style='width:55px;'>등록번호</th><td colspan='2'>").append(clientBusRegNo).append("</td>");
|
||||
html.append("<td class='vl' rowspan='4'>공<br/>급<br/>자</td>");
|
||||
html.append("<th style='width:55px;'>등록번호</th><td colspan='2'>314-81-75146</td></tr>");
|
||||
|
||||
html.append("<tr><th>상 호</th><td>").append(clientNm).append("</td><th style='width:40px;'>성명</th><td>").append(clientCeoNm).append("</td>");
|
||||
html.append("<th>상 호</th><td>주식회사알피에스본사</td><th style='width:40px;'>성명</th><td>이동헌</td></tr>");
|
||||
|
||||
html.append("<tr><th>주 소</th><td colspan='2'>").append(clientAddr).append("</td>");
|
||||
html.append("<th>주 소</th><td colspan='2'>대전광역시 유성구 국제과학10로 8(둔곡동)</td></tr>");
|
||||
|
||||
html.append("<tr><th>업 태</th><td>").append(clientBusType).append("</td><th style='width:40px;'>종목</th><td>").append(clientBusItem).append("</td>");
|
||||
html.append("<th>업 태</th><td>제조업</td><th style='width:40px;'>종목</th><td>금속절삭가공기계,반도체제조용기계</td></tr>");
|
||||
// 공급받는자 / 공급자 (10컬럼)
|
||||
html.append("<table style='margin-top:2px; table-layout:fixed;'>");
|
||||
html.append("<colgroup>");
|
||||
html.append("<col style='width:28px;'><col style='width:62px;'><col><col style='width:45px;'><col style='width:70px;'>");
|
||||
html.append("<col style='width:28px;'><col style='width:62px;'><col><col style='width:45px;'><col style='width:90px;'>");
|
||||
html.append("</colgroup>");
|
||||
html.append("<tr>");
|
||||
html.append("<td rowspan='4' class='vl'>공급받는자</td>");
|
||||
html.append("<td class='lbl'>등록번호</td><td colspan='3'>").append(clientBusRegNo).append("</td>");
|
||||
html.append("<td rowspan='4' class='vl'>공 급 자</td>");
|
||||
html.append("<td class='lbl'>등록번호</td><td colspan='3'>314-81-75146</td></tr>");
|
||||
html.append("<tr><td class='lbl'>상 호</td><td>").append(clientNm).append("</td><td class='lbl'>성명</td><td>").append(clientCeoNm).append("</td>");
|
||||
html.append("<td class='lbl'>상 호</td><td>주식회사알피에스본사</td><td class='lbl'>성명</td><td>이동헌</td></tr>");
|
||||
html.append("<tr><td class='lbl'>주 소</td><td colspan='3'>").append(clientAddr).append("</td>");
|
||||
html.append("<td class='lbl'>주 소</td><td colspan='3'>대전광역시 유성구 국제과학10로 8(둔곡동)</td></tr>");
|
||||
html.append("<tr><td class='lbl'>업 태</td><td>").append(clientBusType).append("</td><td class='lbl'>종목</td><td>").append(clientBusItem).append("</td>");
|
||||
html.append("<td class='lbl'>업 태</td><td>제조업</td><td class='lbl'>종목</td><td style='font-size:9px;'>금속절삭가공기계,반도체제조용기계</td></tr>");
|
||||
html.append("</table>");
|
||||
|
||||
// 납품처/담당자
|
||||
html.append("<table>");
|
||||
html.append("<tr><th style='width:70px;'>납 품 처</th><td>").append(clientNm).append("</td>");
|
||||
html.append("<th style='width:70px;'>전화번호</th><td>").append(clientTelNo).append("</td>");
|
||||
html.append("<th style='width:70px;'>팩스번호</th><td>").append(clientFaxNo).append("</td></tr>");
|
||||
html.append("<tr><th>주 소</th><td>").append(clientAddr).append("</td>");
|
||||
html.append("<th>담 당 자</th><td>").append(writerName).append("</td>");
|
||||
html.append("<th>C.P.번호</th><td></td></tr>");
|
||||
// 납품처 / 담당자 (6컬럼)
|
||||
html.append("<table style='margin-top:-1px; table-layout:fixed;'>");
|
||||
html.append("<colgroup><col style='width:70px;'><col><col style='width:70px;'><col style='width:130px;'><col style='width:70px;'><col style='width:130px;'></colgroup>");
|
||||
html.append("<tr><td class='lbl'>납 품 처</td><td>").append(clientNm).append("</td>");
|
||||
html.append("<td class='lbl'>전화번호</td><td>").append(clientTelNo).append("</td>");
|
||||
html.append("<td class='lbl'>팩스번호</td><td>").append(clientFaxNo).append("</td></tr>");
|
||||
html.append("<tr><td class='lbl'>주 소</td><td>").append(clientAddr).append("</td>");
|
||||
html.append("<td class='lbl'>담 당 자</td><td>").append(writerName).append("</td>");
|
||||
html.append("<td class='lbl'>C.P.번호</td><td></td></tr>");
|
||||
html.append("</table>");
|
||||
|
||||
// 품목
|
||||
html.append("<table>");
|
||||
html.append("<tr><th style='width:30px;'>No.</th><th style='width:90px;'>품번</th><th>품명</th><th>규격</th>");
|
||||
html.append("<th style='width:40px;'>단위</th><th style='width:75px;'>납기일</th>");
|
||||
html.append("<th style='width:50px;'>수량</th><th style='width:70px;'>단가</th><th style='width:80px;'>금액</th></tr>");
|
||||
// 품목 (9컬럼)
|
||||
html.append("<table style='margin-top:-1px; table-layout:fixed;'>");
|
||||
html.append("<colgroup><col style='width:32px;'><col style='width:85px;'><col><col><col style='width:38px;'><col style='width:78px;'><col style='width:48px;'><col style='width:68px;'><col style='width:78px;'></colgroup>");
|
||||
html.append("<tr><th class='lbl'>No.</th><th class='lbl'>품번</th><th class='lbl'>품명</th><th class='lbl'>규격</th>");
|
||||
html.append("<th class='lbl'>단위</th><th class='lbl'>납기일</th><th class='lbl'>수량</th><th class='lbl'>단가</th><th class='lbl'>금액</th></tr>");
|
||||
|
||||
int totalQty = 0;
|
||||
if(itemList != null){
|
||||
@@ -2378,37 +2396,41 @@ public class ApprovalService {
|
||||
totalQty += qty;
|
||||
|
||||
html.append("<tr>");
|
||||
html.append("<td class='center'>").append(i + 1).append("</td>");
|
||||
html.append("<td class='center'>").append(CommonUtils.checkNull(item.get("PART_NO"))).append("</td>");
|
||||
html.append("<td class='tc'>").append(i + 1).append("</td>");
|
||||
html.append("<td class='tc'>").append(CommonUtils.checkNull(item.get("PART_NO"))).append("</td>");
|
||||
html.append("<td>").append(CommonUtils.checkNull(item.get("PART_NAME"))).append("</td>");
|
||||
html.append("<td>").append(CommonUtils.checkNull(item.get("SPEC"))).append("</td>");
|
||||
html.append("<td class='center'>").append(CommonUtils.checkNull(item.get("UNIT_NAME"))).append("</td>");
|
||||
html.append("<td class='center'>").append(CommonUtils.checkNull(item.get("DUE_DATE"))).append("</td>");
|
||||
html.append("<td class='right'>").append(formatNumber(qty)).append("</td>");
|
||||
html.append("<td class='right'>").append(formatNumber(CommonUtils.checkNull(item.get("ORDER_UNIT_PRICE")))).append("</td>");
|
||||
html.append("<td class='right'>").append(formatNumber(CommonUtils.checkNull(item.get("ORDER_SUPPLY_PRICE")))).append("</td>");
|
||||
html.append("<td class='tc'>").append(CommonUtils.checkNull(item.get("UNIT_NAME"))).append("</td>");
|
||||
html.append("<td class='tc'>").append(CommonUtils.checkNull(item.get("DUE_DATE"))).append("</td>");
|
||||
html.append("<td class='tr'>").append(formatNumber(qty)).append("</td>");
|
||||
html.append("<td class='tr'>").append(formatNumber(CommonUtils.checkNull(item.get("ORDER_UNIT_PRICE")))).append("</td>");
|
||||
html.append("<td class='tr'>").append(formatNumber(CommonUtils.checkNull(item.get("ORDER_SUPPLY_PRICE")))).append("</td>");
|
||||
html.append("</tr>");
|
||||
}
|
||||
}
|
||||
|
||||
html.append("<tr class='total-row'><td colspan='6' class='center'>합 계</td>");
|
||||
html.append("<td class='right'>").append(formatNumber(totalQty)).append("</td><td></td>");
|
||||
html.append("<td class='right'>").append(formatNumber(supplyPrice)).append("</td></tr>");
|
||||
// 합계
|
||||
html.append("<tr><td colspan='9' style='text-align:center; background-color:#ffffcc; font-weight:bold; letter-spacing:8px;'>합 계</td></tr>");
|
||||
html.append("<tr><td colspan='6' class='tc' style='font-weight:bold;'></td>");
|
||||
html.append("<td class='tr' style='font-weight:bold;'>").append(formatNumber(totalQty)).append("</td><td class='tr'></td>");
|
||||
html.append("<td class='tr' style='font-weight:bold;'>").append(formatNumber(supplyPrice)).append("</td></tr>");
|
||||
html.append("</table>");
|
||||
|
||||
// 비고
|
||||
html.append("<table>");
|
||||
html.append("<tr><td class='vl' rowspan='3' style='letter-spacing:8px; font-size:13px;'>비 고</td>");
|
||||
// 비고 (4컬럼)
|
||||
html.append("<table style='margin-top:-1px; table-layout:fixed;'>");
|
||||
html.append("<colgroup><col style='width:40px;'><col><col style='width:120px;'><col style='width:150px;'></colgroup>");
|
||||
html.append("<tr><td rowspan='3' class='vl' style='letter-spacing:8px; font-size:13px;'>비 고</td>");
|
||||
html.append("<td rowspan='3'></td>");
|
||||
html.append("<th style='width:120px; letter-spacing:2px;'>공 급 가 액 합 계</th><td class='right' style='width:150px;'>").append(formatNumber(supplyPrice)).append("</td></tr>");
|
||||
html.append("<tr><th style='letter-spacing:2px;'>부 가 가 치 세</th><td class='right'>").append(formatNumber(vat)).append("</td></tr>");
|
||||
html.append("<tr><th style='letter-spacing:5px;'>총 계</th><td class='right' style='font-weight:bold;'>").append(formatNumber(totalAmount)).append("</td></tr>");
|
||||
html.append("<td class='lbl' style='letter-spacing:2px;'>공 급 가 액 합 계</td><td class='tr'>").append(formatNumber(supplyPrice)).append("</td></tr>");
|
||||
html.append("<tr><td class='lbl' style='letter-spacing:2px;'>부 가 가 치 세</td><td class='tr'>").append(formatNumber(vat)).append("</td></tr>");
|
||||
html.append("<tr><td class='lbl' style='letter-spacing:5px;'>총 계</td><td class='tr' style='font-weight:bold;'>").append(formatNumber(totalAmount)).append("</td></tr>");
|
||||
html.append("</table>");
|
||||
// 하단 부가세 구분 + 날짜
|
||||
html.append("<div style='display:flex; justify-content:space-between; padding:3px 5px; font-size:11px; border:1px solid #000; border-top:none;'>");
|
||||
html.append("<span>").append(vatNote).append("</span>");
|
||||
html.append("<span>").append(regDatetime).append("</span>");
|
||||
html.append("</div>");
|
||||
html.append("</div>");
|
||||
|
||||
html.append("</body></html>");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user