구매품의서 반려건 재결재상신 가능하도록 수정. 결재완료, 결재중일 경우 수정불가 기능 추가, 원채버 업로드 응답 오류 수정

This commit is contained in:
2026-03-12 10:58:04 +09:00
parent 68120dc749
commit 80b539dc61
5 changed files with 113 additions and 61 deletions

View File

@@ -392,7 +392,21 @@ body {
}
</style>
<script>
var proposalStatus = "${resultMap.STATUS}";
var amaranthStatus = "${resultMap.AMARANTH_STATUS}";
var isReadOnly = (proposalStatus == "approvalComplete" || proposalStatus == "approvalRequest"
|| amaranthStatus == "complete" || amaranthStatus == "inProcess");
$(document).ready(function(){
// 결재완료/결재중이면 수정 불가 처리
if(isReadOnly){
$("input[type='text']").prop("readonly", true).css("background-color", "#f5f5f5");
$("select").prop("disabled", true).css("background-color", "#f5f5f5");
$("textarea").prop("readonly", true).css("background-color", "#f5f5f5");
$("#btnSave").hide();
$(".date_icon").removeClass("date_icon");
}
// 닫기 버튼
$("#btnClose").click(function(){
self.close();
@@ -408,12 +422,14 @@ $(document).ready(function(){
fn_save();
});
// 날짜 피커 초기화
$(".date_icon").datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: true,
changeYear: true
});
// 날짜 피커 초기화 (수정 가능할 때만)
if(!isReadOnly){
$(".date_icon").datepicker({
dateFormat: 'yy-mm-dd',
changeMonth: true,
changeYear: true
});
}
});
// 숫자 포맷팅
@@ -424,6 +440,10 @@ function formatNumber(num) {
// 저장 함수
function fn_save(){
if(isReadOnly){
Swal.fire({ icon:'warning', title:'수정 불가', text:'결재완료 또는 결재중인 품의서는 수정할 수 없습니다.' });
return;
}
// 품목 정보 수집
var partList = [];
$(".part-row").each(function(){

View File

@@ -1139,6 +1139,14 @@ public class AmaranthApprovalApiClient {
* 원챔버 업로드 응답에서 list 배열의 첫 번째 항목 JSON 추출
*/
public String extractListItemFromUploadResponse(String jsonResponse) {
return extractListItemFromUploadResponse(jsonResponse, null);
}
/**
* 원챔버 업로드 응답에서 list 항목 추출 + name 필드 보강
* 아마란스 프론트엔드(downloadFileLocal)에서 name 필드가 필수
*/
public String extractListItemFromUploadResponse(String jsonResponse, String originalFileName) {
int listIdx = jsonResponse.indexOf("\"list\":[");
if (listIdx == -1) return null;
@@ -1146,7 +1154,6 @@ public class AmaranthApprovalApiClient {
int objStart = jsonResponse.indexOf("{", arrStart);
if (objStart == -1) return null;
// 중첩 중괄호를 고려하여 닫는 중괄호 찾기
int depth = 0;
int objEnd = -1;
for (int i = objStart; i < jsonResponse.length(); i++) {
@@ -1162,7 +1169,15 @@ public class AmaranthApprovalApiClient {
}
if (objEnd == -1) return null;
return jsonResponse.substring(objStart, objEnd + 1);
String listItem = jsonResponse.substring(objStart, objEnd + 1);
// name 필드가 없으면 원본 파일명 주입
if (originalFileName != null && !originalFileName.isEmpty() && !listItem.contains("\"name\"")) {
listItem = listItem.substring(0, listItem.length() - 1)
+ ",\"name\":\"" + escapeJson(originalFileName) + "\"}";
}
return listItem;
}
/**

View File

@@ -643,11 +643,15 @@
)
</insert>
<!-- 기존 매핑 갱신 (재상신 시 - approKey는 유지) -->
<!-- 기존 매핑 갱신 (재상신 시 - 반려 건은 새 approKey로 교체) -->
<update id="updateAmaranthApprovalResubmit" parameterType="map">
UPDATE AMARANTH_APPROVAL SET
APPRO_KEY = #{approKey},
APPROVAL_TITLE = #{approvalTitle},
WRITER = #{writer},
STATUS = 'create',
AMARANTH_DOC_ID = NULL,
DOC_STS = '0',
UPDATE_DATE = NOW()
WHERE TARGET_OBJID = #{targetObjId} AND TARGET_TYPE = #{targetType}
</update>

View File

@@ -4990,9 +4990,13 @@ ORDER BY V.PATH2
SRM.EXECUTOR,
SRM.EXECUTION_DATE,
TO_CHAR(SRM.EXECUTION_DATE, 'YYYY-MM-DD') AS EXECUTION_DATE_TITLE,
SRM.TITLE
SRM.TITLE,
COALESCE(AMR.STATUS, '') AS AMARANTH_STATUS
FROM
SALES_REQUEST_MASTER SRM
LEFT OUTER JOIN AMARANTH_APPROVAL AMR
ON SRM.OBJID::VARCHAR = AMR.TARGET_OBJID
AND AMR.TARGET_TYPE = 'PROPOSAL'
WHERE
SRM.OBJID = #{PROPOSAL_OBJID}
</select>

View File

@@ -1809,7 +1809,7 @@ public class ApprovalService {
String compSeq = CommonUtils.checkNull(paramMap.get("compSeq"), "1000");
String deptSeq = CommonUtils.checkNull(paramMap.get("deptSeq"));
// DB에서 기존 매핑 조회 → 있으면 approKey 재사용, 없으면 신규 생성
// DB에서 기존 매핑 조회 → 상태에 따라 approKey 재사용 또는 신규 생성
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
Map<String, Object> mappingParam = new HashMap();
mappingParam.put("targetType", targetType);
@@ -1821,9 +1821,18 @@ public class ApprovalService {
String approKey;
boolean isNewRecord;
if(existing != null){
approKey = CommonUtils.checkNull(existing.get("APPRO_KEY"));
isNewRecord = false;
System.out.println("=== 기존 approKey 재사용: " + approKey + " ===");
String existingStatus = CommonUtils.checkNull(existing.get("STATUS"));
// 반려/삭제된 건은 새 approKey로 신규 상신 (기존 approKey는 아마란스에 반려 문서로 남아있어 재사용 불가)
if("reject".equals(existingStatus) || "delete".equals(existingStatus)){
approKey = "UB_" + java.util.UUID.randomUUID().toString();
isNewRecord = false;
System.out.println("=== 반려/삭제 건 재상신 - 신규 approKey 생성: " + approKey + " (기존 상태: " + existingStatus + ") ===");
} else {
approKey = CommonUtils.checkNull(existing.get("APPRO_KEY"));
isNewRecord = false;
System.out.println("=== 기존 approKey 재사용: " + approKey + " (상태: " + existingStatus + ") ===");
}
} else {
approKey = "UB_" + java.util.UUID.randomUUID().toString();
isNewRecord = true;
@@ -1973,13 +1982,13 @@ public class ApprovalService {
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();
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse, tempFileName);
if(listItem != null){
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] HTML 업로드 성공");
}
tempFile.delete();
}
} catch(Exception htmlEx){
System.err.println("[첨부파일] HTML 생성/업로드 오류: " + htmlEx.getMessage());
@@ -2018,15 +2027,15 @@ public class ApprovalService {
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);
} else {
System.err.println("[첨부파일] 업로드 응답에서 list 항목 추출 실패: " + originalName);
}
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse, originalName);
if(listItem != null){
if(uploadCount > 0) listItems.append(",");
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] 업로드 성공: " + originalName);
} else {
System.err.println("[첨부파일] 업로드 응답에서 list 항목 추출 실패: " + originalName);
}
}
}
@@ -2097,14 +2106,14 @@ public class ApprovalService {
AMARANTH_BASE_URL, authToken, userHashKey, empSeq, tempFile, tempFileName
);
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse);
if(listItem != null){
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] 주문서 HTML 업로드 성공");
}
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse, tempFileName);
if(listItem != null){
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] 주문서 HTML 업로드 성공");
}
tempFile.delete();
tempFile.delete();
}
} catch(Exception htmlEx){
System.err.println("[첨부파일] 주문서 HTML 생성/업로드 오류: " + htmlEx.getMessage());
@@ -2138,22 +2147,22 @@ public class ApprovalService {
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);
}
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse, originalName);
if(listItem != null){
if(uploadCount > 0) listItems.append(",");
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] 업로드 성공: " + originalName);
}
}
}
if(uploadCount == 0) return null;
if(uploadCount == 0) return null;
String fileListJson = "[" + listItems.toString() + "]";
String fileListEncoded = java.net.URLEncoder.encode(fileListJson, "UTF-8");
String fileListJson = "[" + listItems.toString() + "]";
String fileListEncoded = java.net.URLEncoder.encode(fileListJson, "UTF-8");
System.out.println("[첨부파일] 주문서 총 " + uploadCount + "건 업로드 완료");
System.out.println("[첨부파일] 주문서 총 " + uploadCount + "건 업로드 완료");
return fileListEncoded;
@@ -2484,12 +2493,12 @@ public class ApprovalService {
AMARANTH_BASE_URL, authToken, userHashKey, empSeq, tempFile, tempFileName
);
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse);
if(listItem != null){
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] 견적서 HTML 업로드 성공");
}
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse, tempFileName);
if(listItem != null){
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] 견적서 HTML 업로드 성공");
}
tempFile.delete();
}
@@ -2525,15 +2534,15 @@ public class ApprovalService {
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);
}
String listItem = apiClient.extractListItemFromUploadResponse(uploadResponse, originalName);
if(listItem != null){
if(uploadCount > 0) listItems.append(",");
listItems.append(listItem);
uploadCount++;
System.out.println("[첨부파일] 업로드 성공: " + originalName);
}
}
}
if(uploadCount == 0) return null;