[RAPID] 수주복사 기능 구현 - 버튼/Controller/Service/Mapper

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 15:53:26 +09:00
parent fefba10438
commit 03d8cb481e
4 changed files with 270 additions and 0 deletions

View File

@@ -85,6 +85,50 @@ $(document).ready(function(){
}
});
//수주복사
$("#btnCopy").click(function(){
var selectedData = _tabulGrid.getSelectedData();
if(selectedData.length < 1){
Swal.fire("복사할 행을 선택해주십시오.");
return false;
} else if(selectedData.length > 1){
Swal.fire("한번에 한개의 수주만 복사 가능합니다.");
return false;
}
var sourceObjId = fnc_checkNull(selectedData[0].OBJID);
var contractNo = fnc_checkNull(selectedData[0].CONTRACT_NO);
Swal.fire({
title: '수주복사',
html: '[' + contractNo + '] 수주를 복사하시겠습니까?',
icon: 'question',
showCancelButton: true,
confirmButtonText: '복사',
cancelButtonText: '취소'
}).then((result) => {
if(result.isConfirmed) {
$.ajax({
url: "/contractMgmt/copyEstimateAndOrderInfo.do",
type: "POST",
data: {"sourceObjId": sourceObjId},
dataType: "json",
success: function(data) {
if(data.result == "SUCCESS") {
Swal.fire("복사가 완료되었습니다. (영업번호: " + data.newContractNo + ")");
fn_search();
} else {
Swal.fire("복사 중 오류가 발생했습니다.");
}
},
error: function(jqxhr, status, error) {
Swal.fire("복사 중 오류가 발생했습니다. " + error);
}
});
}
});
});
//결재상신 (Amaranth)
$("#btnApproval").click(function(){
var selectedData = _tabulGrid.getSelectedData();
@@ -1055,6 +1099,7 @@ function openProjectFormPopUp(objId){
</h2>
<div class="btnArea">
<input type="button" value="조회" class="plm_btns" id="btnSearch" name="btnSearch">
<input type="button" value="수주복사" class="plm_btns" id="btnCopy">
<input type="button" value="수주입력" class="plm_btns btnRegist">
<input type="button" value="수주확정" class="plm_btns" id="btnOrderConfirm" style="background-color:#2ecc71; color:#fff;">
<input type="button" value="수주취소" class="plm_btns" id="btnOrderCancel" style="background-color:#e74c3c; color:#fff;">

View File

@@ -2783,6 +2783,23 @@ public class ContractMgmtController {
return "/ajax/ajaxResult";
}
/**
* 수주 복사
*/
@ResponseBody
@RequestMapping(value="/contractMgmt/copyEstimateAndOrderInfo.do", method=RequestMethod.POST)
public Map<String, Object> copyEstimateAndOrderInfo(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map<String, Object> resultMap = new HashMap<String, Object>();
try {
resultMap = contractMgmtService.copyEstimateAndOrderInfo(request, paramMap);
} catch (Exception e) {
e.printStackTrace();
resultMap.put("result", "FAIL");
resultMap.put("message", e.getMessage());
}
return resultMap;
}
/**
* 수주정보 저장
* @param session

View File

@@ -5983,4 +5983,149 @@ WHERE
LIMIT 1
</select>
<!-- 수주복사: 새 영업번호 채번 (MAX+1) -->
<select id="getNextContractNo" parameterType="map" resultType="string">
SELECT TO_CHAR(NOW(),'yy') || 'C-' || LPAD((
COALESCE(MAX(SUBSTRING(CONTRACT_NO FROM 5)::integer), 0) + 1
)::VARCHAR, 4, '0')
FROM CONTRACT_MGMT
WHERE CONTRACT_NO LIKE TO_CHAR(NOW(),'yy') || 'C-%'
</select>
<!-- 수주복사: CONTRACT_MGMT 복사 (CONTRACT_RESULT 빈값) -->
<insert id="copyContractMgmt" parameterType="map">
INSERT INTO CONTRACT_MGMT (
OBJID,
CATEGORY_CD,
CUSTOMER_OBJID,
PRODUCT,
AREA_CD,
CUSTOMER_EQUIP_NAME,
CUSTOMER_PROJECT_NAME,
CUSTOMER_PRODUCTION_NO,
MECHANICAL_TYPE,
PAID_TYPE,
RECEIPT_DATE,
REQ_DEL_DATE,
CONTRACT_RESULT,
PO_NO,
ORDER_DATE,
CONTRACT_CURRENCY,
EXCHANGE_RATE,
REGDATE,
WRITER,
CONTRACT_NO,
IS_DIRECT_ORDER,
ORDER_SUPPLY_PRICE,
ORDER_VAT,
ORDER_TOTAL_AMOUNT
)
SELECT
#{newObjId},
CATEGORY_CD,
CUSTOMER_OBJID,
PRODUCT,
AREA_CD,
CUSTOMER_EQUIP_NAME,
CUSTOMER_PROJECT_NAME,
CUSTOMER_PRODUCTION_NO,
MECHANICAL_TYPE,
PAID_TYPE,
RECEIPT_DATE,
REQ_DEL_DATE,
'',
PO_NO,
ORDER_DATE,
CONTRACT_CURRENCY,
EXCHANGE_RATE,
NOW(),
#{writer},
#{newContractNo},
IS_DIRECT_ORDER,
ORDER_SUPPLY_PRICE,
ORDER_VAT,
ORDER_TOTAL_AMOUNT
FROM CONTRACT_MGMT
WHERE OBJID = #{sourceObjId}
</insert>
<!-- 수주복사: CONTRACT_ITEM 복사 -->
<insert id="copyContractItems" parameterType="map">
INSERT INTO CONTRACT_ITEM (
OBJID,
CONTRACT_OBJID,
SEQ,
PART_OBJID,
PART_NO,
PART_NAME,
QUANTITY,
DUE_DATE,
CUSTOMER_REQUEST,
RETURN_REASON,
REGDATE,
WRITER,
STATUS,
ORDER_QUANTITY,
ORDER_UNIT_PRICE,
ORDER_SUPPLY_PRICE,
ORDER_VAT,
ORDER_TOTAL_AMOUNT
)
SELECT
#{newItemObjId},
#{newContractObjId},
SEQ,
PART_OBJID,
PART_NO,
PART_NAME,
QUANTITY,
DUE_DATE,
CUSTOMER_REQUEST,
RETURN_REASON,
NOW(),
#{writer},
'ACTIVE',
ORDER_QUANTITY,
ORDER_UNIT_PRICE,
ORDER_SUPPLY_PRICE,
ORDER_VAT,
ORDER_TOTAL_AMOUNT
FROM CONTRACT_ITEM
WHERE OBJID = #{sourceItemObjId}
AND STATUS = 'ACTIVE'
</insert>
<!-- 수주복사: CONTRACT_ITEM_SERIAL 복사 -->
<insert id="copyContractItemSerials" parameterType="map">
INSERT INTO CONTRACT_ITEM_SERIAL (
OBJID,
ITEM_OBJID,
SEQ,
SERIAL_NO,
REGDATE,
WRITER,
STATUS
)
SELECT
#{prefix} || SEQ::VARCHAR,
#{newItemObjId},
SEQ,
SERIAL_NO,
NOW(),
#{writer},
'ACTIVE'
FROM CONTRACT_ITEM_SERIAL
WHERE ITEM_OBJID = #{sourceItemObjId}
AND STATUS = 'ACTIVE'
</insert>
<!-- 수주복사: 원본 품목 OBJID 목록 조회 -->
<select id="getActiveItemObjIds" parameterType="map" resultType="string">
SELECT OBJID
FROM CONTRACT_ITEM
WHERE CONTRACT_OBJID = #{sourceObjId}
AND STATUS = 'ACTIVE'
ORDER BY SEQ
</select>
</mapper>

View File

@@ -2591,6 +2591,69 @@ private String encodeImageToBase64(String imagePath) {
return items;
}
/**
* 수주 복사
* 기존 수주의 기본정보 + 품목 + S/N을 복사하여 새 수주 생성 (수주상태만 빈값)
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public Map copyEstimateAndOrderInfo(HttpServletRequest request, Map paramMap){
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try{
sqlSession = SqlMapConfig.getInstance().getSqlSession();
PersonBean person = (PersonBean)request.getSession().getAttribute(Constants.PERSON_BEAN);
String sourceObjId = CommonUtils.checkNull(paramMap.get("sourceObjId"));
String newObjId = CommonUtils.createObjId();
String writer = person.getUserId();
// 1. 새 영업번호 채번 (MAX+1)
String newContractNo = sqlSession.selectOne("contractMgmt.getNextContractNo", paramMap);
// 2. CONTRACT_MGMT 복사
Map<String, Object> copyParam = new HashMap<String, Object>();
copyParam.put("sourceObjId", sourceObjId);
copyParam.put("newObjId", newObjId);
copyParam.put("newContractNo", newContractNo);
copyParam.put("writer", writer);
sqlSession.insert("contractMgmt.copyContractMgmt", copyParam);
// 3. 원본 품목 OBJID 목록 조회
List<String> sourceItemObjIds = sqlSession.selectList("contractMgmt.getActiveItemObjIds", copyParam);
// 4. 품목 + S/N 복사
if(sourceItemObjIds != null) {
for(String sourceItemObjId : sourceItemObjIds) {
String newItemObjId = CommonUtils.createObjId();
Map<String, Object> itemCopyParam = new HashMap<String, Object>();
itemCopyParam.put("sourceItemObjId", sourceItemObjId);
itemCopyParam.put("newItemObjId", newItemObjId);
itemCopyParam.put("newContractObjId", newObjId);
itemCopyParam.put("writer", writer);
sqlSession.insert("contractMgmt.copyContractItems", itemCopyParam);
// S/N 복사
String snPrefix = CommonUtils.createObjId() + "_";
itemCopyParam.put("prefix", snPrefix);
sqlSession.insert("contractMgmt.copyContractItemSerials", itemCopyParam);
}
}
sqlSession.commit();
resultMap.put("result", "SUCCESS");
resultMap.put("newContractNo", newContractNo);
} catch(Exception e){
if(sqlSession != null) sqlSession.rollback();
e.printStackTrace();
resultMap.put("result", "FAIL");
resultMap.put("message", e.getMessage());
} finally {
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
/**
* 견적요청 및 수주 통합 저장
* 견적요청 정보와 수주 정보를 한번에 저장