V20260210 #151
381
WebContent/WEB-INF/view/contractMgmt/orderFormView.jsp
Normal file
381
WebContent/WEB-INF/view/contractMgmt/orderFormView.jsp
Normal file
@@ -0,0 +1,381 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<%@ page import="com.pms.common.utils.*"%>
|
||||
<%@ page import="java.util.*" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
|
||||
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
|
||||
<%@include file="/init.jsp"%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>주문서</title>
|
||||
<style>
|
||||
@media print {
|
||||
body { margin: 0; padding: 10px; }
|
||||
.no-print { display: none !important; }
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 15px 20px;
|
||||
font-family: '맑은 고딕', 'Malgun Gothic', sans-serif;
|
||||
font-size: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
.order-wrap {
|
||||
max-width: 860px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.order-title {
|
||||
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;
|
||||
}
|
||||
.header-row {
|
||||
font-size: 11px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
/* 공통 테이블 */
|
||||
table.doc-tbl {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
table.doc-tbl td, table.doc-tbl th {
|
||||
border: 1px solid #000;
|
||||
padding: 2px 4px;
|
||||
font-size: 11px;
|
||||
vertical-align: middle;
|
||||
word-break: break-all;
|
||||
}
|
||||
table.doc-tbl .vl {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background-color: #e8faff;
|
||||
font-size: 12px;
|
||||
letter-spacing: 5px;
|
||||
}
|
||||
table.doc-tbl .lbl {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
background-color: #e8faff;
|
||||
font-size: 11px;
|
||||
letter-spacing: 3px;
|
||||
}
|
||||
/* 품목 테이블 */
|
||||
table.item-tbl {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.item-tbl th {
|
||||
border: 1px solid #000;
|
||||
padding: 3px 4px;
|
||||
background-color: #e8faff;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
}
|
||||
table.item-tbl td {
|
||||
border: 1px solid #000;
|
||||
padding: 2px 4px;
|
||||
font-size: 11px;
|
||||
}
|
||||
.tc { text-align: center; }
|
||||
.tr { text-align: right; }
|
||||
.total-row td {
|
||||
background-color: #fff8dc;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
padding: 3px 4px;
|
||||
}
|
||||
.btn-area {
|
||||
text-align: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.btn-area button {
|
||||
padding: 5px 18px;
|
||||
margin: 0 4px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
border: 1px solid #999;
|
||||
border-radius: 2px;
|
||||
background: #fff;
|
||||
}
|
||||
.btn-area button.btn-print {
|
||||
background-color: #3085d6;
|
||||
color: white;
|
||||
border-color: #3085d6;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="order-wrap" id="orderContainer">
|
||||
<!-- 제목 -->
|
||||
<div class="order-title">주 문 서</div>
|
||||
|
||||
<!-- 주문일자 / 증빙번호 -->
|
||||
<div class="header-row">주문일자 : <span id="orderDate"></span></div>
|
||||
<div class="header-row">증빙번호 : <span id="poNo"></span></div>
|
||||
|
||||
<!-- 발주자 / 공급자 -->
|
||||
<table class="doc-tbl" style="margin-top:2px;">
|
||||
<colgroup>
|
||||
<col style="width:28px;"><!-- 발주자 세로 -->
|
||||
<col style="width:62px;"><!-- 라벨 -->
|
||||
<col><!-- 값1 -->
|
||||
<col style="width:45px;"><!-- 성명/종목 라벨 -->
|
||||
<col style="width:70px;"><!-- 값2 -->
|
||||
<col style="width:28px;"><!-- 공급자 세로 -->
|
||||
<col style="width:62px;"><!-- 라벨 -->
|
||||
<col><!-- 값1 -->
|
||||
<col style="width:45px;"><!-- 성명/종목 라벨 -->
|
||||
<col style="width:90px;"><!-- 값2 -->
|
||||
</colgroup>
|
||||
<tr>
|
||||
<td rowspan="4" class="vl" style="writing-mode:vertical-rl;">공급받는자</td>
|
||||
<td class="lbl">등록번호</td>
|
||||
<td colspan="3" id="clientBusRegNo"></td>
|
||||
<td rowspan="4" class="vl" style="writing-mode:vertical-rl;">공 급 자</td>
|
||||
<td class="lbl">등록번호</td>
|
||||
<td colspan="3">314-81-75146</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lbl">상 호</td>
|
||||
<td id="clientNm"></td>
|
||||
<td class="lbl">성명</td>
|
||||
<td id="clientCeoNm"></td>
|
||||
<td class="lbl">상 호</td>
|
||||
<td>주식회사알피에스본사</td>
|
||||
<td class="lbl">성명</td>
|
||||
<td>이동헌</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lbl">주 소</td>
|
||||
<td colspan="3" id="clientAddr"></td>
|
||||
<td class="lbl">주 소</td>
|
||||
<td colspan="3">대전광역시 유성구 국제과학10로 8(둔곡동)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lbl">업 태</td>
|
||||
<td id="clientBusType"></td>
|
||||
<td class="lbl">종목</td>
|
||||
<td id="clientBusItem"></td>
|
||||
<td class="lbl">업 태</td>
|
||||
<td>제조업</td>
|
||||
<td class="lbl">종목</td>
|
||||
<td style="font-size:9px;">금속절삭가공기계,반도체제조용기계</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- 납품처 / 담당자 -->
|
||||
<table class="doc-tbl" style="margin-top:-1px;">
|
||||
<colgroup>
|
||||
<col style="width:70px;">
|
||||
<col>
|
||||
<col style="width:70px;">
|
||||
<col style="width:130px;">
|
||||
<col style="width:70px;">
|
||||
<col style="width:130px;">
|
||||
</colgroup>
|
||||
<tr>
|
||||
<td class="lbl">납 품 처</td>
|
||||
<td id="deliveryPlace"></td>
|
||||
<td class="lbl">전화번호</td>
|
||||
<td id="clientTelNo"></td>
|
||||
<td class="lbl">팩스번호</td>
|
||||
<td id="clientFaxNo"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lbl">주 소</td>
|
||||
<td id="deliveryAddr"></td>
|
||||
<td class="lbl">담 당 자</td>
|
||||
<td id="writerName"></td>
|
||||
<td class="lbl">C.P.번호</td>
|
||||
<td id="writerContact"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- 품목 테이블 -->
|
||||
<table class="item-tbl" style="margin-top:-1px;">
|
||||
<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>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No.</th>
|
||||
<th>품번</th>
|
||||
<th>품명</th>
|
||||
<th>규격</th>
|
||||
<th>단위</th>
|
||||
<th>납기일</th>
|
||||
<th>수량</th>
|
||||
<th>단가</th>
|
||||
<th>금액</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="itemBody">
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="total-row">
|
||||
<td colspan="9" style="text-align:center; background-color:#ffffcc; font-weight:bold; letter-spacing:8px;">합 계</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" class="tc" style="font-weight:bold;"></td>
|
||||
<td class="tr" id="totalQty" style="font-weight:bold;"></td>
|
||||
<td class="tr"></td>
|
||||
<td class="tr" id="totalSupplyPrice" style="font-weight:bold;"></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<!-- 비고 (합계 요약) -->
|
||||
<table class="doc-tbl" style="margin-top:-1px;">
|
||||
<colgroup>
|
||||
<col style="width:40px;">
|
||||
<col>
|
||||
<col style="width:120px;">
|
||||
<col style="width:150px;">
|
||||
</colgroup>
|
||||
<tr>
|
||||
<td rowspan="3" class="vl" style="writing-mode:vertical-rl; letter-spacing:8px; font-size:13px;">비 고</td>
|
||||
<td rowspan="3"></td>
|
||||
<td class="lbl" style="letter-spacing:2px;">공 급 가 액 합 계</td>
|
||||
<td class="tr" id="summarySupply"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lbl" style="letter-spacing:2px;">부 가 가 치 세</td>
|
||||
<td class="tr" id="summaryVat"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="lbl" style="letter-spacing:5px;">총 계</td>
|
||||
<td class="tr" id="summaryTotal" style="font-weight:bold;"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- 하단 부가세 구분 + 날짜 -->
|
||||
<div style="display:flex; justify-content:space-between; padding:3px 5px; font-size:11px; border:1px solid #000; border-top:none;">
|
||||
<span id="vatNote"></span>
|
||||
<span id="regDatetime"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-area no-print">
|
||||
<button class="btn-print" onclick="window.print();">인쇄</button>
|
||||
<button onclick="window.close();">닫기</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var objId = '${info.OBJID}';
|
||||
|
||||
$(document).ready(function(){
|
||||
fn_loadOrderForm();
|
||||
});
|
||||
|
||||
function fn_loadOrderForm(){
|
||||
$.ajax({
|
||||
url: "/contractMgmt/getOrderFormData.do",
|
||||
type: "POST",
|
||||
data: { objId: objId },
|
||||
dataType: "json",
|
||||
success: function(data){
|
||||
if(data.result === "success"){
|
||||
fn_renderOrderForm(data.info, data.items);
|
||||
} else {
|
||||
Swal.fire("주문서 데이터를 불러올 수 없습니다.");
|
||||
}
|
||||
},
|
||||
error: function(){
|
||||
Swal.fire("주문서 데이터 조회 중 오류가 발생했습니다.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fn_renderOrderForm(info, items){
|
||||
// 주문일자
|
||||
var orderDate = fnc_checkNull(info.ORDER_DATE);
|
||||
if(orderDate !== ''){
|
||||
var parts = orderDate.split('-');
|
||||
if(parts.length === 3){
|
||||
$("#orderDate").text(parts[0] + '년 ' + parts[1] + '월 ' + parts[2] + '일');
|
||||
} else {
|
||||
$("#orderDate").text(orderDate);
|
||||
}
|
||||
}
|
||||
// 중방번호 = PO_NO (발주번호)
|
||||
$("#poNo").text(fnc_checkNull(info.PO_NO));
|
||||
|
||||
// 발주자(고객사)
|
||||
$("#clientBusRegNo").text(fnc_checkNull(info.CLIENT_BUS_REG_NO));
|
||||
$("#clientNm").text(fnc_checkNull(info.CLIENT_NM));
|
||||
$("#clientCeoNm").text(fnc_checkNull(info.CLIENT_CEO_NM));
|
||||
$("#clientAddr").text(fnc_checkNull(info.CLIENT_ADDR));
|
||||
$("#clientBusType").text(fnc_checkNull(info.CLIENT_BUS_TYPE));
|
||||
$("#clientBusItem").text(fnc_checkNull(info.CLIENT_BUS_ITEM));
|
||||
$("#clientTelNo").text(fnc_checkNull(info.CLIENT_TEL_NO));
|
||||
$("#clientFaxNo").text(fnc_checkNull(info.CLIENT_FAX_NO));
|
||||
|
||||
// 납품처
|
||||
$("#deliveryPlace").text(fnc_checkNull(info.CLIENT_NM));
|
||||
$("#deliveryAddr").text(fnc_checkNull(info.CLIENT_ADDR));
|
||||
$("#writerName").text(fnc_checkNull(info.WRITER_NAME));
|
||||
|
||||
// 품목
|
||||
var html = '';
|
||||
var totalQty = 0;
|
||||
var totalSupply = 0;
|
||||
if(items && items.length > 0){
|
||||
for(var i = 0; i < items.length; i++){
|
||||
var item = items[i];
|
||||
var qty = parseFloat(item.ORDER_QUANTITY || 0);
|
||||
var unitPrice = parseFloat(item.ORDER_UNIT_PRICE || 0);
|
||||
var supplyPrice = parseFloat(item.ORDER_SUPPLY_PRICE || 0);
|
||||
totalQty += qty;
|
||||
totalSupply += supplyPrice;
|
||||
|
||||
html += '<tr>';
|
||||
html += '<td class="tc">' + (i + 1) + '</td>';
|
||||
html += '<td class="tc">' + fnc_checkNull(item.PART_NO) + '</td>';
|
||||
html += '<td>' + fnc_checkNull(item.PART_NAME) + '</td>';
|
||||
html += '<td>' + fnc_checkNull(item.SPEC) + '</td>';
|
||||
html += '<td class="tc">' + fnc_checkNull(item.UNIT_NAME) + '</td>';
|
||||
html += '<td class="tc">' + fnc_checkNull(item.DUE_DATE) + '</td>';
|
||||
html += '<td class="tr">' + (qty > 0 ? fn_fmt(qty) : '') + '</td>';
|
||||
html += '<td class="tr">' + (unitPrice > 0 ? fn_fmt(unitPrice) : '') + '</td>';
|
||||
html += '<td class="tr">' + (supplyPrice > 0 ? fn_fmt(supplyPrice) : '') + '</td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
}
|
||||
$("#itemBody").html(html);
|
||||
$("#totalQty").text(totalQty > 0 ? fn_fmt(totalQty) : '');
|
||||
$("#totalSupplyPrice").text(totalSupply > 0 ? fn_fmt(totalSupply) : '');
|
||||
|
||||
// 합계
|
||||
var sp = parseFloat(info.ORDER_SUPPLY_PRICE || 0);
|
||||
var vt = parseFloat(info.ORDER_VAT || 0);
|
||||
var ta = parseFloat(info.ORDER_TOTAL_AMOUNT || 0);
|
||||
|
||||
$("#summarySupply").text(sp > 0 ? fn_fmt(sp) : '');
|
||||
$("#summaryVat").text(vt > 0 ? fn_fmt(vt) : '');
|
||||
$("#summaryTotal").text(ta > 0 ? fn_fmt(ta) : '');
|
||||
$("#vatNote").text(fnc_checkNull(info.VAT_NOTE));
|
||||
$("#regDatetime").text(fnc_checkNull(info.REG_DATETIME));
|
||||
}
|
||||
|
||||
function fn_fmt(n){
|
||||
return Number(n).toLocaleString();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -85,30 +85,48 @@ $(document).ready(function(){
|
||||
}
|
||||
});
|
||||
|
||||
//결재상신
|
||||
//결재상신 (Amaranth)
|
||||
$("#btnApproval").click(function(){
|
||||
var selectedData = _tabulGrid.getSelectedData();
|
||||
if(selectedData.length<1){
|
||||
if(selectedData.length < 1){
|
||||
Swal.fire("결재상신할 행을 선택해주십시오.");
|
||||
return false;
|
||||
}else if(selectedData.length>1){
|
||||
} else if(selectedData.length > 1){
|
||||
Swal.fire("한번에 한개의 결재만 가능합니다.");
|
||||
return false;
|
||||
}else{
|
||||
|
||||
var targetStatus = fnc_checkNull(selectedData[0].APPR_STATUS);
|
||||
var status = fnc_checkNull(selectedData[0].STATUS);
|
||||
|
||||
if(targetStatus == "결재완료" || targetStatus == "결재중" || status == "cancel"){
|
||||
Swal.fire("작성중/결재반려인 상태만 결재상신 가능합니다.");
|
||||
} else {
|
||||
var amaranthStatus = fnc_checkNull(selectedData[0].ORDER_AMARANTH_STATUS);
|
||||
var objId = fnc_checkNull(selectedData[0].OBJID);
|
||||
var contractNo = fnc_checkNull(selectedData[0].CONTRACT_NO);
|
||||
var hasOrderData = parseInt(selectedData[0].HAS_ORDER_DATA) || 0;
|
||||
|
||||
if(hasOrderData == 0){
|
||||
Swal.fire("수주 품목을 먼저 등록해주세요.");
|
||||
return false;
|
||||
}else{
|
||||
if(confirm("결재상신 하시겠습니까?")){
|
||||
var objId = fnc_checkNull(selectedData[0].OBJID);
|
||||
var title = encodeURIComponent(fnc_checkNull(selectedData[0].CONTRACT_NO));
|
||||
window.open("/approval/registApproval.do?targetType=CONTRACT_ORDER&targetObjId="+objId+"&approvalTitle="+title,"registApproval","width=700,height=700");
|
||||
}
|
||||
}
|
||||
|
||||
if(amaranthStatus == "inProcess"){
|
||||
Swal.fire("결재 진행중인 건은 상신할 수 없습니다.");
|
||||
return false;
|
||||
} else if(amaranthStatus == "complete"){
|
||||
Swal.fire("결재 완료된 건은 상신할 수 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: '결재상신',
|
||||
html: '결재상신 하시겠습니까?',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '결재상신',
|
||||
cancelButtonText: '취소'
|
||||
}).then((result) => {
|
||||
if(result.isConfirmed) {
|
||||
fn_openAmaranthApproval(objId, contractNo);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -252,18 +270,35 @@ var columns = [
|
||||
var objid = fnc_checkNull(cell.getData().OBJID);
|
||||
fn_FileRegist(objid,"ORDER_DOC","ORDER_DOC","CU01_CNT");
|
||||
}
|
||||
},
|
||||
// 16. 고객사요청사항
|
||||
{headerHozAlign : 'center', hozAlign : 'left', minWidth : 100, widthGrow: 1, title : '고객사요청사항', field : 'CUSTOMER_REQUEST' },
|
||||
// 17. 결재상태
|
||||
{headerHozAlign : 'center', hozAlign : 'center', minWidth : 60, widthGrow: 0.7, title : '결재상태', field : 'APPR_STATUS',
|
||||
formatter:fnc_createGridAnchorTag,
|
||||
cellClick:function(e, cell){
|
||||
var APPROVAL_OBJID = fnc_checkNull(cell.getData().APPROVAL_OBJID);
|
||||
var ROUTE_OBJID = fnc_checkNull(cell.getData().ROUTE_OBJID);
|
||||
if(APPROVAL_OBJID != '' || ROUTE_OBJID != ''){
|
||||
approval_form(APPROVAL_OBJID,ROUTE_OBJID);
|
||||
},
|
||||
// 16. 주문서 (자동생성 뷰)
|
||||
{headerHozAlign : 'center', hozAlign : 'center', minWidth : 50, widthGrow: 0.5, title : '주문서', field : 'HAS_ORDER_DATA',
|
||||
formatter: function(cell){
|
||||
var value = parseInt(cell.getValue()) || 0;
|
||||
if(value > 0){
|
||||
return '<img src="/images/icon/doc_view.png" style="width:16px;height:16px;cursor:pointer;" onerror="this.outerHTML=\'<span style=color:#3085d6;cursor:pointer;font-weight:bold;>보기</span>\'">';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
cellClick: function(e, cell){
|
||||
var hasData = parseInt(cell.getValue()) || 0;
|
||||
if(hasData > 0){
|
||||
var objid = fnc_checkNull(cell.getData().OBJID);
|
||||
fn_openOrderFormView(objid);
|
||||
}
|
||||
}
|
||||
},
|
||||
// 17. 고객사요청사항
|
||||
{headerHozAlign : 'center', hozAlign : 'left', minWidth : 100, widthGrow: 1, title : '고객사요청사항', field : 'CUSTOMER_REQUEST' },
|
||||
// 17. 결재상태 (Amaranth) - 주문서 전용
|
||||
{headerHozAlign : 'center', hozAlign : 'center', minWidth : 60, widthGrow: 0.7, title : '결재상태', field : 'ORDER_APPR_STATUS',
|
||||
formatter: function(cell){
|
||||
var val = fnc_checkNull(cell.getValue());
|
||||
if(val == '결재중') return "<span style='color:#e67e22; font-weight:bold;'>" + val + "</span>";
|
||||
if(val == '결재완료') return "<span style='color:#27ae60; font-weight:bold;'>" + val + "</span>";
|
||||
if(val == '반려') return "<span style='color:#e74c3c; font-weight:bold;'>" + val + "</span>";
|
||||
if(val == '작성중') return "<span style='color:#3498db;'>" + val + "</span>";
|
||||
return val;
|
||||
}
|
||||
},
|
||||
// 18. 환종
|
||||
@@ -413,11 +448,43 @@ function fn_delete(){
|
||||
}
|
||||
}
|
||||
|
||||
function approval_form(APPROVAL_OBJID,ROUTE_OBJID){
|
||||
|
||||
url = "/approval/approvalDetail.do?approvalObjId="+APPROVAL_OBJID+"&routeObjId="+ROUTE_OBJID;
|
||||
|
||||
fn_centerPopup(650,400,url,'approvalDetailPopup')
|
||||
// Amaranth10 전자결재 SSO 팝업 열기
|
||||
function fn_openAmaranthApproval(objId, contractNo) {
|
||||
var title = "주문서 결재" + (contractNo ? " - " + contractNo : "");
|
||||
|
||||
$.ajax({
|
||||
url: "/approval/getAmaranthSsoUrl.do",
|
||||
type: "POST",
|
||||
data: {
|
||||
"targetType": "CONTRACT_ORDER",
|
||||
"targetObjId": objId,
|
||||
"approvalTitle": title,
|
||||
"outProcessCode": "${AMARANTH_OUT_PROCESS_CODE}",
|
||||
"formId": "",
|
||||
"compSeq": "1000",
|
||||
"deptSeq": ""
|
||||
},
|
||||
dataType: "json",
|
||||
success: function(data) {
|
||||
if(data.resultCode == 0 && data.resultData && data.resultData.fullUrl) {
|
||||
var fullUrl = data.resultData.fullUrl;
|
||||
window.open(fullUrl, "amaranthApproval", "width=1200,height=900,scrollbars=yes,resizable=yes");
|
||||
} else {
|
||||
Swal.fire("결재 연동 오류: " + (data.resultMsg || "알 수 없는 오류"));
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("Amaranth SSO URL 요청 오류:", error);
|
||||
Swal.fire("결재 시스템 연동 중 오류가 발생했습니다.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function fn_openOrderFormView(objId){
|
||||
var popup_width = 950;
|
||||
var popup_height = 800;
|
||||
var url = "/contractMgmt/orderFormView.do?objId=" + objId;
|
||||
window.open(url, "orderFormView_" + objId, "width=" + popup_width + ",height=" + popup_height + ",menubar=no,scrollbars=yes,resizable=yes");
|
||||
}
|
||||
|
||||
function fn_FileRegist(objId, docType, docTypeName, columnField){
|
||||
|
||||
@@ -756,4 +756,58 @@
|
||||
ORDER BY SEQ
|
||||
</select>
|
||||
|
||||
<!-- 주문서 기본정보 조회 (결재 본문용) -->
|
||||
<select id="getOrderInfoForApproval" parameterType="map" resultType="map">
|
||||
SELECT
|
||||
CM.OBJID,
|
||||
CM.CONTRACT_NO,
|
||||
CM.PO_NO,
|
||||
CM.ORDER_DATE,
|
||||
CM.CUSTOMER_OBJID,
|
||||
CODE_NAME(CM.CATEGORY_CD) AS CATEGORY_NAME,
|
||||
CODE_NAME(CM.CONTRACT_CURRENCY) AS CURRENCY_NAME,
|
||||
CM.EXCHANGE_RATE,
|
||||
CM.ORDER_SUPPLY_PRICE,
|
||||
CM.ORDER_VAT,
|
||||
CM.ORDER_TOTAL_AMOUNT,
|
||||
CASE
|
||||
WHEN CM.PAID_TYPE = 'paid' THEN '부가세별도'
|
||||
WHEN CM.PAID_TYPE = 'free' THEN '부가세미포함'
|
||||
ELSE ''
|
||||
END AS VAT_NOTE,
|
||||
(SELECT CLIENT_NM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_NM,
|
||||
(SELECT BUS_REG_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_BUS_REG_NO,
|
||||
(SELECT CEO_NM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_CEO_NM,
|
||||
(SELECT ADDR1 FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_ADDR,
|
||||
(SELECT BUS_TYPE FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_BUS_TYPE,
|
||||
(SELECT BUS_ITEM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_BUS_ITEM,
|
||||
(SELECT TEL_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_TEL_NO,
|
||||
(SELECT FAX_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_FAX_NO,
|
||||
(SELECT DEPT_NAME || ' ' || USER_NAME FROM USER_INFO WHERE USER_ID = CM.WRITER) AS WRITER_NAME,
|
||||
TO_CHAR(CM.REGDATE, 'YYYY-MM-DD HH24:MI:SS') AS REG_DATETIME
|
||||
FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID::VARCHAR = #{targetObjId}
|
||||
</select>
|
||||
|
||||
<!-- 주문서 품목 리스트 조회 (결재 본문용) -->
|
||||
<select id="getOrderItemsForApproval" parameterType="map" resultType="map">
|
||||
SELECT
|
||||
CI.SEQ,
|
||||
COALESCE(PM.PART_NO, CI.PART_NO) AS PART_NO,
|
||||
COALESCE(PM.PART_NAME, CI.PART_NAME) AS PART_NAME,
|
||||
PM.SPEC,
|
||||
CODE_NAME(PM.UNIT) AS UNIT_NAME,
|
||||
CI.DUE_DATE,
|
||||
CI.ORDER_QUANTITY,
|
||||
CI.ORDER_UNIT_PRICE,
|
||||
CI.ORDER_SUPPLY_PRICE,
|
||||
CI.ORDER_VAT,
|
||||
CI.ORDER_TOTAL_AMOUNT
|
||||
FROM CONTRACT_ITEM CI
|
||||
LEFT JOIN PART_MNG PM ON CI.PART_OBJID = PM.OBJID
|
||||
WHERE CI.CONTRACT_OBJID::VARCHAR = #{targetObjId}
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
ORDER BY CI.SEQ
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -2534,6 +2534,7 @@ public class ContractMgmtController {
|
||||
|
||||
request.setAttribute("code_map",code_map);
|
||||
request.setAttribute("actionType",actionType);
|
||||
request.setAttribute("AMARANTH_OUT_PROCESS_CODE", com.pms.common.utils.Constants.AMARANTH_OUT_PROCESS_CODE);
|
||||
//request.setAttribute("LIST", list);
|
||||
|
||||
}catch(Exception e){
|
||||
@@ -2542,6 +2543,50 @@ public class ContractMgmtController {
|
||||
return returnUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서관리 - 주문서 뷰 팝업
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@RequestMapping("/contractMgmt/orderFormView.do")
|
||||
public String orderFormView(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
|
||||
String objId = CommonUtils.checkNull(paramMap.get("objId"));
|
||||
try {
|
||||
Map info = new HashMap();
|
||||
info.put("OBJID", objId);
|
||||
request.setAttribute("info", info);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "/contractMgmt/orderFormView";
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서관리 - 주문서 데이터 AJAX 조회
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@ResponseBody
|
||||
@RequestMapping("/contractMgmt/getOrderFormData.do")
|
||||
public Map getOrderFormData(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
|
||||
Map result = new HashMap();
|
||||
try {
|
||||
String objId = CommonUtils.checkNull(paramMap.get("objId"));
|
||||
Map<String, Object> queryParam = new HashMap<>();
|
||||
queryParam.put("objId", objId);
|
||||
|
||||
Map info = contractMgmtService.getOrderFormInfo(queryParam);
|
||||
List<Map> items = contractMgmtService.getOrderFormItems(queryParam);
|
||||
|
||||
result.put("result", "success");
|
||||
result.put("info", info);
|
||||
result.put("items", items);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
result.put("result", "fail");
|
||||
result.put("message", e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서관리 - 주문서관리 목록 페이징
|
||||
* @param request
|
||||
|
||||
@@ -555,17 +555,25 @@
|
||||
ORDER BY LOG_TIME DESC
|
||||
LIMIT 1
|
||||
) AS MAIL_SEND_DATE
|
||||
,CASE
|
||||
WHEN AMR.STATUS = 'complete' THEN '결재완료'
|
||||
WHEN AMR.STATUS = 'inProcess' THEN '결재중'
|
||||
WHEN AMR.STATUS = 'reject' THEN '반려'
|
||||
WHEN AMR.STATUS = 'create' THEN '작성중'
|
||||
WHEN AMR.STATUS = 'notRequired' THEN '결재불필요'
|
||||
ELSE ''
|
||||
END AS APPR_STATUS
|
||||
,COALESCE(AMR.STATUS, '') AS AMARANTH_STATUS
|
||||
,A.APPROVAL_OBJID
|
||||
,A.ROUTE_OBJID
|
||||
,CASE
|
||||
WHEN AMR.STATUS = 'complete' THEN '결재완료'
|
||||
WHEN AMR.STATUS = 'inProcess' THEN '결재중'
|
||||
WHEN AMR.STATUS = 'reject' THEN '반려'
|
||||
WHEN AMR.STATUS = 'create' THEN '작성중'
|
||||
WHEN AMR.STATUS = 'notRequired' THEN '결재불필요'
|
||||
ELSE ''
|
||||
END AS APPR_STATUS
|
||||
,COALESCE(AMR.STATUS, '') AS AMARANTH_STATUS
|
||||
,CASE
|
||||
WHEN AMR_ORDER.STATUS = 'complete' THEN '결재완료'
|
||||
WHEN AMR_ORDER.STATUS = 'inProcess' THEN '결재중'
|
||||
WHEN AMR_ORDER.STATUS = 'reject' THEN '반려'
|
||||
WHEN AMR_ORDER.STATUS = 'create' THEN '작성중'
|
||||
ELSE ''
|
||||
END AS ORDER_APPR_STATUS
|
||||
,COALESCE(AMR_ORDER.STATUS, '') AS ORDER_AMARANTH_STATUS
|
||||
,A.APPROVAL_OBJID
|
||||
,A.ROUTE_OBJID
|
||||
,(SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1) AS EST_OBJID
|
||||
-- 최근 차수 견적서 합계 정보
|
||||
,(SELECT TOTAL_AMOUNT FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID ORDER BY REGDATE DESC LIMIT 1) AS EST_TOTAL_AMOUNT
|
||||
@@ -701,6 +709,14 @@
|
||||
AND RETURN_REASON != ''
|
||||
LIMIT 1
|
||||
) AS RETURN_REASON_SUMMARY
|
||||
,(
|
||||
SELECT COUNT(1) FROM CONTRACT_ITEM
|
||||
WHERE CONTRACT_OBJID = T.OBJID
|
||||
AND STATUS = 'ACTIVE'
|
||||
AND ORDER_QUANTITY IS NOT NULL
|
||||
AND ORDER_QUANTITY != ''
|
||||
AND ORDER_QUANTITY != '0'
|
||||
) AS HAS_ORDER_DATA
|
||||
FROM
|
||||
CONTRACT_MGMT AS T
|
||||
LEFT OUTER JOIN
|
||||
@@ -741,9 +757,12 @@
|
||||
AND TARGET_TYPE IN ('CONTRACT_ESTIMATE')
|
||||
) A
|
||||
ON (SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1)::numeric = A.TARGET_OBJID
|
||||
LEFT OUTER JOIN AMARANTH_APPROVAL AMR
|
||||
ON (SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1)::VARCHAR = AMR.TARGET_OBJID
|
||||
AND AMR.TARGET_TYPE = 'CONTRACT_ESTIMATE'
|
||||
LEFT OUTER JOIN AMARANTH_APPROVAL AMR
|
||||
ON (SELECT objid FROM ESTIMATE_TEMPLATE WHERE CONTRACT_OBJID = T.OBJID order by regdate desc limit 1)::VARCHAR = AMR.TARGET_OBJID
|
||||
AND AMR.TARGET_TYPE = 'CONTRACT_ESTIMATE'
|
||||
LEFT OUTER JOIN AMARANTH_APPROVAL AMR_ORDER
|
||||
ON T.OBJID::VARCHAR = AMR_ORDER.TARGET_OBJID
|
||||
AND AMR_ORDER.TARGET_TYPE = 'CONTRACT_ORDER'
|
||||
)
|
||||
</sql>
|
||||
|
||||
@@ -5782,4 +5801,59 @@ WHERE
|
||||
)
|
||||
</insert>
|
||||
|
||||
<!-- 주문서 뷰용 기본정보 조회 (수주 + 고객사) -->
|
||||
<select id="getOrderFormInfo" parameterType="map" resultType="com.pms.common.UpperKeyMap">
|
||||
SELECT
|
||||
CM.OBJID,
|
||||
CM.CONTRACT_NO,
|
||||
CM.PO_NO,
|
||||
CM.ORDER_DATE,
|
||||
CM.CUSTOMER_OBJID,
|
||||
CODE_NAME(CM.CATEGORY_CD) AS CATEGORY_NAME,
|
||||
CODE_NAME(CM.CONTRACT_CURRENCY) AS CURRENCY_NAME,
|
||||
CM.EXCHANGE_RATE,
|
||||
CM.ORDER_SUPPLY_PRICE,
|
||||
CM.ORDER_VAT,
|
||||
CM.ORDER_TOTAL_AMOUNT,
|
||||
CASE
|
||||
WHEN CM.PAID_TYPE = 'paid' THEN '부가세별도'
|
||||
WHEN CM.PAID_TYPE = 'free' THEN '부가세미포함'
|
||||
ELSE ''
|
||||
END AS VAT_NOTE,
|
||||
(SELECT CLIENT_NM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_NM,
|
||||
(SELECT BUS_REG_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_BUS_REG_NO,
|
||||
(SELECT CEO_NM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_CEO_NM,
|
||||
(SELECT ADDR1 FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_ADDR,
|
||||
(SELECT BUS_TYPE FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_BUS_TYPE,
|
||||
(SELECT BUS_ITEM FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_BUS_ITEM,
|
||||
(SELECT TEL_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_TEL_NO,
|
||||
(SELECT FAX_NO FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_FAX_NO,
|
||||
(SELECT EMAIL FROM CLIENT_MNG C WHERE 'C_' || C.OBJID::VARCHAR = CM.CUSTOMER_OBJID) AS CLIENT_EMAIL,
|
||||
(SELECT DEPT_NAME || ' ' || USER_NAME FROM USER_INFO WHERE USER_ID = CM.WRITER) AS WRITER_NAME,
|
||||
TO_CHAR(CM.REGDATE, 'YYYY-MM-DD HH24:MI:SS') AS REG_DATETIME
|
||||
FROM CONTRACT_MGMT CM
|
||||
WHERE CM.OBJID::VARCHAR = #{objId}
|
||||
</select>
|
||||
|
||||
<!-- 주문서 뷰용 품목 리스트 조회 -->
|
||||
<select id="getOrderFormItems" parameterType="map" resultType="com.pms.common.UpperKeyMap">
|
||||
SELECT
|
||||
CI.SEQ,
|
||||
COALESCE(PM.PART_NO, CI.PART_NO) AS PART_NO,
|
||||
COALESCE(PM.PART_NAME, CI.PART_NAME) AS PART_NAME,
|
||||
PM.SPEC,
|
||||
CODE_NAME(PM.UNIT) AS UNIT_NAME,
|
||||
CI.DUE_DATE,
|
||||
CI.ORDER_QUANTITY,
|
||||
CI.ORDER_UNIT_PRICE,
|
||||
CI.ORDER_SUPPLY_PRICE,
|
||||
CI.ORDER_VAT,
|
||||
CI.ORDER_TOTAL_AMOUNT
|
||||
FROM CONTRACT_ITEM CI
|
||||
LEFT JOIN PART_MNG PM ON CI.PART_OBJID = PM.OBJID
|
||||
WHERE CI.CONTRACT_OBJID::VARCHAR = #{objId}
|
||||
AND CI.STATUS = 'ACTIVE'
|
||||
ORDER BY CI.SEQ
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -484,6 +484,40 @@ public class ContractMgmtService {
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서 뷰용 기본정보 조회
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public Map getOrderFormInfo(Map<String, Object> paramMap){
|
||||
SqlSession sqlSession = null;
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
return sqlSession.selectOne("contractMgmt.getOrderFormInfo", paramMap);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if(sqlSession != null) sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서 뷰용 품목 리스트 조회
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public List<Map> getOrderFormItems(Map<String, Object> paramMap){
|
||||
SqlSession sqlSession = null;
|
||||
try {
|
||||
sqlSession = SqlMapConfig.getInstance().getSqlSession();
|
||||
return sqlSession.selectList("contractMgmt.getOrderFormItems", paramMap);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
return new ArrayList<>();
|
||||
} finally {
|
||||
if(sqlSession != null) sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
public List overlapOrder(HttpServletRequest request,Map paramMap){
|
||||
List<Map<String,Object>> resultList = new ArrayList();
|
||||
SqlSession sqlSession = null;
|
||||
|
||||
@@ -1842,6 +1842,8 @@ public class ApprovalService {
|
||||
try {
|
||||
if("CONTRACT_ESTIMATE".equals(targetType)) {
|
||||
fileListEncoded = uploadEstimateFilesToOneChamber(apiClient, empSeq, targetObjId);
|
||||
} else if("CONTRACT_ORDER".equals(targetType)) {
|
||||
fileListEncoded = uploadOrderFilesToOneChamber(apiClient, empSeq, targetObjId);
|
||||
} else {
|
||||
fileListEncoded = uploadFilesToOneChamber(apiClient, empSeq, targetObjId, targetType);
|
||||
}
|
||||
@@ -2047,6 +2049,363 @@ public class ApprovalService {
|
||||
* 견적서 첨부파일을 원챔버에 업로드하고 fileList (URL 인코딩) 반환
|
||||
* @return URL 인코딩된 fileList JSON 문자열 (파일 없으면 null)
|
||||
*/
|
||||
/**
|
||||
* 주문서 데이터를 원챔버에 HTML로 업로드
|
||||
*/
|
||||
private String uploadOrderFilesToOneChamber(
|
||||
com.pms.api.AmaranthApprovalApiClient apiClient,
|
||||
String empSeq, String targetObjId) throws Exception {
|
||||
|
||||
if(targetObjId == null || targetObjId.isEmpty()) return null;
|
||||
|
||||
SqlSession sqlSession = SqlMapConfig.getInstance().getSqlSession(true);
|
||||
try {
|
||||
Map<String, String> authResult = apiClient.getAuthToken(AMARANTH_BASE_URL, empSeq);
|
||||
if(!"true".equals(authResult.get("success"))){
|
||||
throw new Exception("파일 업로드용 인증 토큰 발급 실패: " + authResult.get("resultMsg"));
|
||||
}
|
||||
String authToken = authResult.get("authToken");
|
||||
String userHashKey = authResult.get("hashKey");
|
||||
|
||||
StringBuilder listItems = new StringBuilder();
|
||||
int uploadCount = 0;
|
||||
|
||||
// 주문서 본문을 HTML 파일로 생성하여 업로드
|
||||
try {
|
||||
Map<String, Object> orderParam = new HashMap<String, Object>();
|
||||
orderParam.put("targetObjId", targetObjId);
|
||||
Map<String, Object> orderInfo = sqlSession.selectOne("approval.getOrderInfoForApproval", orderParam);
|
||||
|
||||
if(orderInfo != null){
|
||||
orderInfo = CommonUtils.toUpperCaseMapKey(orderInfo);
|
||||
String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO"));
|
||||
|
||||
List<Map> itemList = sqlSession.selectList("approval.getOrderItemsForApproval", orderParam);
|
||||
|
||||
String fullHtml = buildOrderFormFileHtml(orderInfo, itemList);
|
||||
|
||||
String tempFileName = "주문서_" + contractNo + ".html";
|
||||
java.io.File tempFile = java.io.File.createTempFile("order_", ".html");
|
||||
java.io.OutputStreamWriter writer = new java.io.OutputStreamWriter(
|
||||
new java.io.FileOutputStream(tempFile), "UTF-8");
|
||||
writer.write(fullHtml);
|
||||
writer.close();
|
||||
|
||||
System.out.println("[첨부파일] 주문서 HTML 생성: " + tempFileName + " (" + tempFile.length() + " bytes)");
|
||||
|
||||
String uploadResponse = apiClient.uploadFileToOneChamber(
|
||||
AMARANTH_BASE_URL, authToken, userHashKey, empSeq, tempFile, tempFileName
|
||||
);
|
||||
|
||||
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse);
|
||||
if(listItem != null){
|
||||
listItems.append(listItem);
|
||||
uploadCount++;
|
||||
System.out.println("[첨부파일] 주문서 HTML 업로드 성공");
|
||||
}
|
||||
|
||||
tempFile.delete();
|
||||
}
|
||||
} catch(Exception htmlEx){
|
||||
System.err.println("[첨부파일] 주문서 HTML 생성/업로드 오류: " + htmlEx.getMessage());
|
||||
}
|
||||
|
||||
// ATTACH_FILE_INFO에서 기존 첨부파일도 업로드 (주문서 첨부)
|
||||
Map<String, Object> fileParam = new HashMap<String, Object>();
|
||||
fileParam.put("targetObjId", targetObjId);
|
||||
List<Map<String, Object>> fileList = sqlSession.selectList("common.getFileList", fileParam);
|
||||
|
||||
if(fileList != null && !fileList.isEmpty()){
|
||||
System.out.println("[첨부파일] 주문서(" + targetObjId + ") 기존 첨부파일 " + fileList.size() + "건 발견");
|
||||
|
||||
for(Map<String, Object> fileInfo : fileList){
|
||||
String savedFileName = CommonUtils.checkNull(fileInfo.get("saved_file_name"));
|
||||
String realFileName = CommonUtils.checkNull(fileInfo.get("real_file_name"));
|
||||
String filePath = CommonUtils.checkNull(fileInfo.get("file_path"));
|
||||
|
||||
if(savedFileName.isEmpty()) continue;
|
||||
|
||||
String fullPath = filePath + "/" + savedFileName;
|
||||
java.io.File physicalFile = new java.io.File(fullPath);
|
||||
if(!physicalFile.exists()){
|
||||
System.err.println("[첨부파일] 파일 미존재: " + fullPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
String originalName = realFileName.isEmpty() ? savedFileName : realFileName;
|
||||
|
||||
String uploadResponse = apiClient.uploadFileToOneChamber(
|
||||
AMARANTH_BASE_URL, authToken, userHashKey, empSeq, physicalFile, originalName
|
||||
);
|
||||
|
||||
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse);
|
||||
if(listItem != null){
|
||||
if(uploadCount > 0) listItems.append(",");
|
||||
listItems.append(listItem);
|
||||
uploadCount++;
|
||||
System.out.println("[첨부파일] 업로드 성공: " + originalName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(uploadCount == 0) return null;
|
||||
|
||||
String fileListJson = "[" + listItems.toString() + "]";
|
||||
String fileListEncoded = java.net.URLEncoder.encode(fileListJson, "UTF-8");
|
||||
|
||||
System.out.println("[첨부파일] 주문서 총 " + uploadCount + "건 업로드 완료");
|
||||
|
||||
return fileListEncoded;
|
||||
|
||||
} finally {
|
||||
if(sqlSession != null) sqlSession.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서 Amaranth 결재 본문용 HTML 생성
|
||||
*/
|
||||
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 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")));
|
||||
String clientAddr = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_ADDR")));
|
||||
String clientBusType = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_TYPE")));
|
||||
String clientBusItem = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_ITEM")));
|
||||
String clientTelNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_TEL_NO")));
|
||||
String clientFaxNo = escapeHtml(CommonUtils.checkNull(orderInfo.get("CLIENT_FAX_NO")));
|
||||
String writerName = escapeHtml(CommonUtils.checkNull(orderInfo.get("WRITER_NAME")));
|
||||
String supplyPrice = CommonUtils.checkNull(orderInfo.get("ORDER_SUPPLY_PRICE"));
|
||||
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")));
|
||||
|
||||
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;'";
|
||||
|
||||
html.append("<div style='font-family:맑은 고딕; max-width:800px; margin:0 auto;'>");
|
||||
html.append("<h2 style='text-align:center; letter-spacing:15px;'>주 문 서</h2>");
|
||||
|
||||
// 헤더
|
||||
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;'>");
|
||||
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("</tr>");
|
||||
|
||||
int totalQty = 0;
|
||||
if(itemList != null){
|
||||
for(int i = 0; i < itemList.size(); i++){
|
||||
Map item = CommonUtils.toUpperCaseMapKey(itemList.get(i));
|
||||
int qty = 0;
|
||||
try { qty = Integer.parseInt(CommonUtils.checkNull(item.get("ORDER_QUANTITY"), "0")); } catch(Exception e){}
|
||||
totalQty += qty;
|
||||
String unitPrice = CommonUtils.checkNull(item.get("ORDER_UNIT_PRICE"));
|
||||
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("</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></table>");
|
||||
|
||||
// 비고(합계 요약)
|
||||
html.append("<table style='width:100%; border-collapse:collapse;'>");
|
||||
html.append("<tr><td rowspan='3' " + TH + " style='width:30px; writing-mode:vertical-rl;'>비고</td>");
|
||||
html.append("<td " + TH + ">공급가액 합계</td><td " + TD_R + " style='width:150px;'>").append(formatNumber(supplyPrice)).append("</td>");
|
||||
html.append("<td rowspan='3' " + TD_C + ">").append(vatNote).append("</td></tr>");
|
||||
html.append("<tr><td " + TH + ">부가가치세</td><td " + TD_R + ">").append(formatNumber(vat)).append("</td></tr>");
|
||||
html.append("<tr><td " + TH + ">총 계</td><td " + TD_R + " style='font-weight:bold;'>").append(formatNumber(totalAmount)).append("</td></tr>");
|
||||
html.append("</table>");
|
||||
|
||||
html.append("</div>");
|
||||
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 주문서 결재 첨부파일용 전체 HTML 생성
|
||||
*/
|
||||
private String buildOrderFormFileHtml(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 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"));
|
||||
String clientAddr = CommonUtils.checkNull(orderInfo.get("CLIENT_ADDR"));
|
||||
String clientBusType = CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_TYPE"));
|
||||
String clientBusItem = CommonUtils.checkNull(orderInfo.get("CLIENT_BUS_ITEM"));
|
||||
String clientTelNo = CommonUtils.checkNull(orderInfo.get("CLIENT_TEL_NO"));
|
||||
String clientFaxNo = CommonUtils.checkNull(orderInfo.get("CLIENT_FAX_NO"));
|
||||
String writerName = CommonUtils.checkNull(orderInfo.get("WRITER_NAME"));
|
||||
String supplyPrice = CommonUtils.checkNull(orderInfo.get("ORDER_SUPPLY_PRICE"));
|
||||
String vat = CommonUtils.checkNull(orderInfo.get("ORDER_VAT"));
|
||||
String totalAmount = CommonUtils.checkNull(orderInfo.get("ORDER_TOTAL_AMOUNT"));
|
||||
String vatNote = CommonUtils.checkNull(orderInfo.get("VAT_NOTE"));
|
||||
String regDatetime = CommonUtils.checkNull(orderInfo.get("REG_DATETIME"));
|
||||
|
||||
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("</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("<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>");
|
||||
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>");
|
||||
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>");
|
||||
|
||||
int totalQty = 0;
|
||||
if(itemList != null){
|
||||
for(int i = 0; i < itemList.size(); i++){
|
||||
Map item = CommonUtils.toUpperCaseMapKey(itemList.get(i));
|
||||
int qty = 0;
|
||||
try { qty = Integer.parseInt(CommonUtils.checkNull(item.get("ORDER_QUANTITY"), "0")); } catch(Exception e){}
|
||||
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>").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("</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("</table>");
|
||||
|
||||
// 비고
|
||||
html.append("<table>");
|
||||
html.append("<tr><td class='vl' rowspan='3'>비<br/>고</td>");
|
||||
html.append("<th style='width:100px;'>공급가액 합계</th><td class='right' style='width:140px;'>").append(formatNumber(supplyPrice)).append("</td>");
|
||||
html.append("<td rowspan='3' class='center'>").append(vatNote).append("</td>");
|
||||
html.append("<td rowspan='3' style='text-align:right; vertical-align:bottom; font-size:10px;'>").append(regDatetime).append("</td></tr>");
|
||||
html.append("<tr><th>부 가 가 치 세</th><td class='right'>").append(formatNumber(vat)).append("</td></tr>");
|
||||
html.append("<tr><th>총 계</th><td class='right' style='font-weight:bold;'>").append(formatNumber(totalAmount)).append("</td></tr>");
|
||||
html.append("</table>");
|
||||
|
||||
html.append("</body></html>");
|
||||
|
||||
return html.toString();
|
||||
}
|
||||
|
||||
private String uploadEstimateFilesToOneChamber(
|
||||
com.pms.api.AmaranthApprovalApiClient apiClient,
|
||||
String empSeq, String targetObjId) throws Exception {
|
||||
@@ -2499,6 +2858,8 @@ public class ApprovalService {
|
||||
System.out.println("구매요청 상태 변경 - targetObjId: " + targetObjId + " → " + proposalStatus);
|
||||
} else if("CONTRACT_ESTIMATE".equals(targetType)){
|
||||
System.out.println("견적서 결재 상태 변경 - targetObjId: " + targetObjId + " → " + internalStatus);
|
||||
} else if("CONTRACT_ORDER".equals(targetType)){
|
||||
System.out.println("주문서 결재 상태 변경 - targetObjId: " + targetObjId + " → " + internalStatus);
|
||||
} else if("ECR".equals(targetType)){
|
||||
System.out.println("ECR 콜백 처리 - targetObjId: " + targetObjId + " (AMARANTH_APPROVAL 상태만 관리)");
|
||||
}
|
||||
@@ -2623,6 +2984,21 @@ public class ApprovalService {
|
||||
title = "견적서 결재 - " + estimateNo;
|
||||
}
|
||||
}
|
||||
} else if("CONTRACT_ORDER".equals(targetType) && !targetObjId.isEmpty()){
|
||||
Map<String, Object> orderParam = new HashMap();
|
||||
orderParam.put("targetObjId", targetObjId);
|
||||
Map<String, Object> orderInfo = sqlSession.selectOne("approval.getOrderInfoForApproval", orderParam);
|
||||
|
||||
if(orderInfo != null){
|
||||
orderInfo = CommonUtils.toUpperCaseMapKey(orderInfo);
|
||||
List<Map> itemList = sqlSession.selectList("approval.getOrderItemsForApproval", orderParam);
|
||||
contentsHtml = buildOrderContentsHtml(orderInfo, itemList);
|
||||
|
||||
String contractNo = CommonUtils.checkNull(orderInfo.get("CONTRACT_NO"));
|
||||
if(!contractNo.isEmpty()){
|
||||
title = "주문서 결재 - " + contractNo;
|
||||
}
|
||||
}
|
||||
} else if("ECR".equals(targetType) && !targetObjId.isEmpty()){
|
||||
Map<String, Object> ecrParam = new HashMap();
|
||||
ecrParam.put("OBJID", targetObjId);
|
||||
|
||||
Reference in New Issue
Block a user