품의서 양식 개발, 입고관리 등...

This commit is contained in:
2025-12-02 15:10:41 +09:00
parent f97399d45b
commit 4c1967cd63
10 changed files with 1133 additions and 73 deletions

View File

@@ -3833,12 +3833,50 @@
WHERE OBJID = #{mbomHeaderObjid}
</update>
<!-- MBOM_DETAIL 삭제 (수정 시 기존 데이터 삭제 후 재삽입) -->
<!-- MBOM_DETAIL 전체 삭제 (신규 저장 시 사용 - 기존 호환성 유지) -->
<delete id="deleteMbomDetail" parameterType="map">
DELETE FROM MBOM_DETAIL
WHERE MBOM_HEADER_OBJID = #{mbomHeaderObjid}
</delete>
<!-- MBOM_DETAIL 개별 삭제 (UPSERT용) -->
<delete id="deleteMbomDetailByObjid" parameterType="map">
DELETE FROM MBOM_DETAIL
WHERE OBJID = #{objid}
</delete>
<!-- MBOM_DETAIL 업데이트 (UPSERT용) -->
<update id="updateMbomDetail" parameterType="map">
UPDATE MBOM_DETAIL
SET
PARENT_OBJID = NULLIF(#{parentObjid}, ''),
SEQ = NULLIF(#{seq}::TEXT, '')::INTEGER,
LEVEL = NULLIF(#{level}::TEXT, '')::INTEGER,
PART_OBJID = NULLIF(#{partObjid}, ''),
PART_NO = NULLIF(#{partNo}, ''),
PART_NAME = NULLIF(#{partName}, ''),
QTY = NULLIF(#{qty}::TEXT, '')::NUMERIC,
UNIT = NULLIF(#{unit}, ''),
SUPPLY_TYPE = NULLIF(#{supplyType}, ''),
MAKE_OR_BUY = NULLIF(#{makeOrBuy}, ''),
RAW_MATERIAL_PART_NO = NULLIF(#{rawMaterialPartNo}, ''),
RAW_MATERIAL_SPEC = NULLIF(#{rawMaterialSpec}, ''),
RAW_MATERIAL = NULLIF(#{rawMaterial}, ''),
RAW_MATERIAL_SIZE = NULLIF(#{rawMaterialSize}, ''),
PROCESSING_VENDOR = NULLIF(#{processingVendor}, ''),
PROCESSING_DEADLINE = NULLIF(#{processingDeadline}, ''),
GRINDING_DEADLINE = NULLIF(#{grindingDeadline}, ''),
REQUIRED_QTY = NULLIF(#{requiredQty}::TEXT, '')::NUMERIC,
ORDER_QTY = NULLIF(#{orderQty}::TEXT, '')::NUMERIC,
PRODUCTION_QTY = NULLIF(#{productionQty}::TEXT, '')::NUMERIC,
STOCK_QTY = NULLIF(#{stockQty}::TEXT, '')::NUMERIC,
SHORTAGE_QTY = NULLIF(#{shortageQty}::TEXT, '')::NUMERIC,
EDITER = #{sessionUserId},
EDIT_DATE = NOW(),
REMARK = NULLIF(#{remark}, '')
WHERE OBJID = #{objid}
</update>
<!-- MBOM_HISTORY 삽입 -->
<insert id="insertMbomHistory" parameterType="map">
INSERT INTO MBOM_HISTORY (

View File

@@ -4191,8 +4191,8 @@ SELECT POM.OBJID
,POM.MULTI_YN
,CASE WHEN POM.MULTI_MASTER_YN = 'Y' THEN '' ELSE POM.MULTI_YN END MULTI_YN_MAKED
<!-- ,S1.TOTAL_PO_QTY -->
<!-- ,(SELECT SUM(ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) AS TOTAL_PO_QTY -->
,(SELECT SUM(REAL_ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) AS TOTAL_PO_QTY
,(SELECT SUM(ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) AS TOTAL_PO_QTY
<!--,(SELECT SUM(REAL_ORDER_QTY::NUMERIC) FROM PURCHASE_ORDER_PART AS O WHERE POM.OBJID::VARCHAR = O.PURCHASE_ORDER_MASTER_OBJID) AS TOTAL_PO_QTY -->
,S1.CUR_DELIVERY_DATE
,S1.TOTAL_DELIVERY_QTY
<!-- ,(S1.TOTAL_PO_QTY - S1.TOTAL_DELIVERY_QTY - S1.TOTAL_DEFECT_QTY) AS NON_DELIVERY_QTY -->
@@ -4261,7 +4261,8 @@ SELECT POM.OBJID
ON POM.CONTRACT_MGMT_OBJID = CM.OBJID
<!-- ,PROJECT_MGMT AS CM -->
<!-- WHERE POM.CONTRACT_MGMT_OBJID = CM.OBJID -->
WHERE POM.STATUS = 'approvalComplete' <!-- A.APPR_STATUS = 'complete' -->/*결재완료*/
WHERE 1=1
<!-- AND POM.STATUS = 'approvalComplete' --> <!-- A.APPR_STATUS = 'complete' -->/*결재완료*/
<!-- AND POM.SALES_STATUS = 'OK' -->
<!-- AND (POM.SALES_STATUS = 'OK' OR POM.TYPE = '0001538' ) -->
AND (MULTI_MASTER_YN = 'Y' OR NVL(MULTI_MASTER_YN, '') != 'Y' AND NVL(MULTI_YN, '') != 'Y')

View File

@@ -3828,14 +3828,72 @@ ORDER BY V.PATH2
END AS STATUS_TITLE,
SRM.WRITER,
(SELECT DEPT_NAME||' '||USER_NAME FROM USER_INFO WHERE USER_ID = SRM.WRITER) AS WRITER_NAME,
(SELECT DEPT_NAME FROM USER_INFO WHERE USER_ID = SRM.WRITER) AS WRITER_DEPT,
SRM.REGDATE,
TO_CHAR(SRM.REGDATE,'YYYY-MM-DD') AS REGDATE_TITLE,
TO_CHAR(SRM.REGDATE,'YYYY-MM-DD HH24:MI') AS REGDATE_TIME,
SRM.REMARK,
SRM.DOC_TYPE
SRM.DOC_TYPE,
-- 품의서 추가 컬럼
SRM.RECIPIENT_REF,
SRM.EXECUTOR,
SRM.EXECUTION_DATE,
TO_CHAR(SRM.EXECUTION_DATE, 'YYYY-MM-DD') AS EXECUTION_DATE_TITLE,
SRM.TITLE
FROM
SALES_REQUEST_MASTER SRM
WHERE
SRM.OBJID = #{PROPOSAL_OBJID}
</select>
<!-- 품의서 품목 리스트 조회 -->
<select id="getProposalPartList" parameterType="map" resultType="map">
SELECT
ROW_NUMBER() OVER(ORDER BY SRP.REGDATE) AS RNUM,
SRP.OBJID,
SRP.PART_OBJID,
PM.PART_NO,
PM.PART_NAME,
PM.SPEC,
PM.MATERIAL,
SRP.UNIT,
COALESCE(
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = SRP.UNIT),
(SELECT CODE_NAME FROM COMM_CODE CC WHERE CC.CODE_ID = PM.UNIT)
) AS UNIT_TITLE,
SRP.QTY,
SRP.UNIT_PRICE,
SRP.TOTAL_PRICE,
SRP.VENDOR_PM,
(SELECT SUPPLY_NAME FROM ADMIN_SUPPLY_MNG WHERE OBJID::VARCHAR = SRP.VENDOR_PM) AS VENDOR_NAME,
SRP.REMARK,
SRP.DELIVERY_REQUEST_DATE,
SRP.DELIVERY_REQUEST_DATE AS DELIVERY_REQUEST_DATE_TITLE
FROM
SALES_REQUEST_PART SRP
LEFT JOIN PART_MNG PM ON SRP.PART_OBJID::VARCHAR = PM.OBJID::VARCHAR
WHERE
SRP.SALES_REQUEST_MASTER_OBJID = #{PROPOSAL_OBJID}
ORDER BY SRP.REGDATE
</select>
<!-- 품의서 마스터 정보 수정 (수신및참조, 시행자, 시행일자, 제목) -->
<update id="updateProposalMaster" parameterType="map">
UPDATE SALES_REQUEST_MASTER SET
RECIPIENT_REF = #{RECIPIENT_REF},
EXECUTOR = #{EXECUTOR},
EXECUTION_DATE = CASE WHEN #{EXECUTION_DATE} IS NOT NULL AND #{EXECUTION_DATE} != '' THEN #{EXECUTION_DATE}::DATE ELSE NULL END,
TITLE = #{TITLE}
WHERE OBJID = #{PROPOSAL_OBJID}
</update>
<!-- 품의서 품목 정보 수정 (납기일, 단위, 목적) -->
<update id="updateProposalPart" parameterType="map">
UPDATE SALES_REQUEST_PART SET
DELIVERY_REQUEST_DATE = CASE WHEN #{DELIVERY_REQUEST_DATE} IS NOT NULL AND #{DELIVERY_REQUEST_DATE} != '' THEN #{DELIVERY_REQUEST_DATE} ELSE NULL END,
UNIT = #{UNIT},
REMARK = #{REMARK}
WHERE OBJID = #{PART_OBJID}
</update>
</mapper>

View File

@@ -1276,12 +1276,24 @@ public class SalesMngController {
public String proposalFormPopUp(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map resultMap = new HashMap();
Map code_map = new HashMap();
ArrayList approvalList = new ArrayList();
List<Map> partList = new ArrayList();
try {
String proposalObjId = CommonUtils.checkNull(paramMap.get("PROPOSAL_OBJID"));
if(!"".equals(proposalObjId)){
resultMap = commonService.selectOne("salesMng.getProposalInfo", request, paramMap);
// 결재 정보 조회
Map approvalParam = new HashMap();
approvalParam.put("OBJID", proposalObjId);
approvalList = approvalService.getApprovalLine(request, approvalParam);
// 품의서 품목 리스트 조회
Map partParam = new HashMap();
partParam.put("PROPOSAL_OBJID", proposalObjId);
partList = commonService.selectList("salesMng.getProposalPartList", request, partParam);
} else {
resultMap.put("OBJID", CommonUtils.createObjId());
resultMap.put("STATUS", "create");
@@ -1293,6 +1305,8 @@ public class SalesMngController {
code_map.put("order_type", commonService.bizMakeOptionList("0001822", (String)resultMap.get("ORDER_TYPE"), "common.getCodeselect"));
// 제품구분
code_map.put("product_name", commonService.bizMakeOptionList("0000016", (String)resultMap.get("PRODUCT_NAME"), "common.getCodeselect"));
// 단위 코드 목록 (UNIT_CD: 단위)
code_map.put("unit_list", commonService.bizMakeOptionList("0001399", "", "common.getCodeselect"));
} catch (Exception e) {
e.printStackTrace();
@@ -1300,6 +1314,8 @@ public class SalesMngController {
request.setAttribute("resultMap", resultMap);
request.setAttribute("code_map", code_map);
request.setAttribute("approvalList", approvalList);
request.setAttribute("partList", partList);
return "/salesMng/proposalFormPopUp";
}
@@ -1388,4 +1404,47 @@ public class SalesMngController {
public Map createProposalFromPurchaseList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
return createProposal(request, paramMap);
}
/**
* 품의서 저장 (마스터 + 품목)
* @param request
* @param paramMap
* @return
*/
@ResponseBody
@RequestMapping("/salesMng/saveProposal.do")
public Map saveProposal(HttpServletRequest request, @RequestParam Map<String, Object> paramMap){
Map resultMap = new HashMap();
SqlSession sqlSession = null;
try {
sqlSession = SqlMapConfig.getInstance().getSqlSession(false);
// 1. 마스터 정보 저장
sqlSession.update("salesMng.updateProposalMaster", paramMap);
// 2. 품목 정보 저장 (JSON 배열로 전달받음)
String partListJson = CommonUtils.checkNull(paramMap.get("PART_LIST"));
if(!"".equals(partListJson)) {
List<Map<String, Object>> partList = JsonUtil.JsonToList(partListJson);
for(Map part : partList) {
sqlSession.update("salesMng.updateProposalPart", part);
}
}
sqlSession.commit();
resultMap.put("resultFlag", "S");
resultMap.put("message", "저장되었습니다.");
} catch (Exception e) {
if(sqlSession != null) sqlSession.rollback();
e.printStackTrace();
resultMap.put("resultFlag", "F");
resultMap.put("message", "저장 중 오류가 발생했습니다: " + e.getMessage());
} finally {
if(sqlSession != null) sqlSession.close();
}
return resultMap;
}
}

View File

@@ -1361,107 +1361,100 @@ public class ProductionPlanningService {
}
}
// M-BOM 업데이트
// M-BOM 헤더 업데이트
paramMap.put("mbomHeaderObjid", existingMbom.get("OBJID"));
sqlSession.update("productionplanning.updateMbomHeader", paramMap);
// 삭제 전에 기존 데이터 백업 (PROPOSAL_DATE, VENDOR, NET_QTY, PO_QTY 등 보존)
// 기존 데이터 조회
Map<String, Object> queryParam = new HashMap<>();
queryParam.put("mbomHeaderObjid", existingMbom.get("OBJID")); // camelCase로 수정
queryParam.put("mbomHeaderObjid", existingMbom.get("OBJID"));
List<Map> oldMbomDetails = sqlSession.selectList("productionplanning.getMbomDetailList", queryParam);
// OBJID를 키로 하는 맵 생성 (빠른 조회)
// 기존 OBJID Set 생성
java.util.Set<String> existingObjids = new java.util.HashSet<>();
Map<String, Map> existingDataMap = new HashMap<>();
if(oldMbomDetails != null) {
for(Map detail : oldMbomDetails) {
detail = CommonUtils.toUpperCaseMapKey(detail);
String objid = CommonUtils.checkNull(detail.get("OBJID"));
if(!objid.isEmpty()) {
existingObjids.add(objid);
existingDataMap.put(objid, detail);
}
}
}
sqlSession.delete("productionplanning.deleteMbomDetail", paramMap);
// JSP에서 넘어온 OBJID Set 생성
java.util.Set<String> newObjids = new java.util.HashSet<>();
// 새 상세 데이터 삽입
// UPSERT 처리
if(mbomData != null && !mbomData.isEmpty()) {
for(Map<String, Object> item : mbomData) {
item.put("mbomHeaderObjid", existingMbom.get("OBJID"));
item.put("sessionUserId", userId);
// SEQ가 없으면 기존 SEQ 유지 (JSP에서 전송된 seq 사용)
// 없는 경우에만 새로 부여
// SEQ 기본값
if(item.get("seq") == null || "".equals(item.get("seq"))) {
item.put("seq", 999); // 임시값 (나중에 정렬 필요)
item.put("seq", 999);
}
// 기존 항목인 경우 objid와 childObjid 유지
// 새 항목인 경우에만 생성
String objid = CommonUtils.checkNull(item.get("objid"));
String childObjid = CommonUtils.checkNull(item.get("childObjid"));
// 신규 항목: objid가 비어있을 때만
if("".equals(objid)) {
objid = CommonUtils.createObjId();
item.put("objid", objid);
}
if("".equals(childObjid)) {
childObjid = objid; // 새 항목은 objid와 동일
childObjid = objid;
item.put("childObjid", childObjid);
}
// 기존 데이터에서 보존해야 할 값들 복원
newObjids.add(objid);
// 기존 데이터에서 보존할 값 복원
Map existingData = existingDataMap.get(objid);
if(existingData != null) {
// PROPOSAL_DATE가 JSP에서 안 넘어왔으면 기존 값 사용
if(item.get("proposalDate") == null || "".equals(item.get("proposalDate"))) {
Object proposalDate = existingData.get("PROPOSAL_DATE");
if(proposalDate != null) {
item.put("proposalDate", proposalDate);
System.out.println("PROPOSAL_DATE 복원: " + objid + " -> " + proposalDate);
}
Object val = existingData.get("PROPOSAL_DATE");
if(val != null) item.put("proposalDate", val);
}
// VENDOR가 JSP에서 안 넘어왔으면 기존 값 사용
if(item.get("vendor") == null || "".equals(item.get("vendor"))) {
Object vendor = existingData.get("VENDOR");
if(vendor != null) {
item.put("vendor", vendor);
System.out.println("VENDOR 복원: " + objid + " -> " + vendor);
}
Object val = existingData.get("VENDOR");
if(val != null) item.put("vendor", val);
}
// NET_QTY가 JSP에서 안 넘어왔으면 기존 값 사용
if(item.get("netQty") == null || "".equals(item.get("netQty"))) {
Object netQty = existingData.get("NET_QTY");
if(netQty != null) {
item.put("netQty", netQty);
}
Object val = existingData.get("NET_QTY");
if(val != null) item.put("netQty", val);
}
// PO_QTY가 JSP에서 안 넘어왔으면 기존 값 사용
if(item.get("poQty") == null || "".equals(item.get("poQty"))) {
Object poQty = existingData.get("PO_QTY");
if(poQty != null) {
item.put("poQty", poQty);
}
Object val = existingData.get("PO_QTY");
if(val != null) item.put("poQty", val);
}
}
// LEVEL이 없으면 기본값 1 설정
// LEVEL 기본값
if(item.get("level") == null || "".equals(item.get("level"))) {
item.put("level", 1);
}
System.out.println("UPDATE M-BOM DETAIL: seq=" + item.get("seq") +
", level=" + item.get("level") +
", partNo=" + item.get("partNo") +
", parentObjid=" + item.get("parentObjid") +
", childObjid=" + childObjid);
sqlSession.insert("productionplanning.insertMbomDetail", item);
// UPSERT: 기존 항목이면 UPDATE, 신규면 INSERT
if(existingObjids.contains(objid)) {
sqlSession.update("productionplanning.updateMbomDetail", item);
} else {
sqlSession.insert("productionplanning.insertMbomDetail", item);
}
}
}
// DELETE: DB에 있는데 JSP에 없는 항목 삭제
for(String existingObjid : existingObjids) {
if(!newObjids.contains(existingObjid)) {
Map<String, Object> deleteParam = new HashMap<>();
deleteParam.put("objid", existingObjid);
sqlSession.delete("productionplanning.deleteMbomDetailByObjid", deleteParam);
}
}