From cd4f5afe879be0b2a839ff6b1097d2b46a8a5929 Mon Sep 17 00:00:00 2001 From: leeheejin Date: Tue, 25 Nov 2025 13:58:07 +0900 Subject: [PATCH] auto commit --- .../com/pms/mapper/productionplanning.xml | 604 +++++++++++++++--- .../classes/com/pms/mapper/salesMng.xml | 122 ++++ .../view/productionplanning/mBomMgmtList.jsp | 43 ++ .../view/salesMng/purchaseListFormPopUp.jsp | 407 ++++++++++++ ...ase_list_columns_to_sales_request_part.sql | 63 ++ database/create_purchase_list_table.sql | 80 +++ src/com/pms/mapper/salesMng.xml | 122 ++++ .../controller/SalesMngController.java | 49 ++ .../salesmgmt/service/SalesMngService.java | 91 +++ 9 files changed, 1479 insertions(+), 102 deletions(-) create mode 100644 WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp create mode 100644 database/add_purchase_list_columns_to_sales_request_part.sql create mode 100644 database/create_purchase_list_table.sql diff --git a/WebContent/WEB-INF/classes/com/pms/mapper/productionplanning.xml b/WebContent/WEB-INF/classes/com/pms/mapper/productionplanning.xml index 5555df3..869dea1 100644 --- a/WebContent/WEB-INF/classes/com/pms/mapper/productionplanning.xml +++ b/WebContent/WEB-INF/classes/com/pms/mapper/productionplanning.xml @@ -2944,29 +2944,47 @@ LIMIT 1), '' ) AS EBOM_REGDATE, - COALESCE(PM.MBOM_STATUS, '') AS MBOM_STATUS, + -- M-BOM 상태: 새 MBOM_HEADER 테이블에서 조회 COALESCE( - (SELECT PBR.PART_NO - FROM PART_BOM_REPORT PBR - WHERE PBR.OBJID::VARCHAR = PM.BOM_REPORT_OBJID - AND PM.MBOM_STATUS = 'Y' - LIMIT 1), + (SELECT + CASE + WHEN COUNT(*) > 0 THEN 'Y' + ELSE COALESCE(PM.MBOM_STATUS, '') + END + FROM MBOM_HEADER MH + WHERE MH.PROJECT_OBJID = PM.OBJID::VARCHAR + AND MH.STATUS = 'Y' + LIMIT 1), + COALESCE(PM.MBOM_STATUS, '') + ) AS MBOM_STATUS, + -- M-BOM 품번: 새 MBOM_HEADER 테이블에서 조회 + COALESCE( + (SELECT MH.MBOM_NO + FROM MBOM_HEADER MH + WHERE MH.PROJECT_OBJID = PM.OBJID::VARCHAR + AND MH.STATUS = 'Y' + ORDER BY MH.REGDATE DESC + LIMIT 1), '' ) AS MBOM_PART_NO, '1.0' AS MBOM_VERSION, + -- M-BOM 저장일: 새 MBOM_HEADER 테이블에서 조회 COALESCE( - (SELECT TO_CHAR(PBR.REGDATE, 'YYYY-MM-DD') - FROM PART_BOM_REPORT PBR - WHERE PBR.OBJID::VARCHAR = PM.BOM_REPORT_OBJID - AND PM.MBOM_STATUS = 'Y' - LIMIT 1), + (SELECT TO_CHAR(MH.REGDATE, 'YYYY-MM-DD') + FROM MBOM_HEADER MH + WHERE MH.PROJECT_OBJID = PM.OBJID::VARCHAR + AND MH.STATUS = 'Y' + ORDER BY MH.REGDATE DESC + LIMIT 1), TO_CHAR(PM.REGDATE, 'YYYY-MM-DD') ) AS MBOM_REGDATE FROM PROJECT_MGMT PM LEFT JOIN CONTRACT_MGMT CM ON PM.CONTRACT_OBJID = CM.OBJID + LEFT OUTER JOIN CONTRACT_ITEM CI ON PM.CONTRACT_OBJID = CI.CONTRACT_OBJID + AND PM.PART_OBJID = CI.PART_OBJID -- CONTRACT_ITEM과 LEFT JOIN하여 품목별로 펼쳐서 보이기 - LEFT JOIN CONTRACT_ITEM CI ON CM.OBJID::VARCHAR = CI.CONTRACT_OBJID + -- LEFT JOIN CONTRACT_ITEM CI ON CM.OBJID::VARCHAR = CI.CONTRACT_OBJID AND CI.STATUS = 'ACTIVE' WHERE 1=1 AND PM.PROJECT_NO IS NOT NULL @@ -3024,6 +3042,10 @@ PM.BOM_REPORT_OBJID, PM.PART_NO, PM.PART_NAME, + PM.SOURCE_BOM_TYPE, + PM.SOURCE_EBOM_OBJID, + PM.SOURCE_MBOM_OBJID, + PM.QUANTITY, COALESCE( (SELECT PBR.PART_NO FROM PART_BOM_REPORT PBR @@ -3268,21 +3290,6 @@ BPQ.SEQ - - - SELECT - PBR.OBJID, - PBR.PART_NO AS MBOM_PART_NO, - TO_CHAR(PBR.REGDATE, 'YYYY-MM-DD HH24:MI:SS') AS REGDATE, - PBR.REGUSER, - COALESCE(PBR.REMARK, '') AS REMARK, - PBR.STATUS + MH.OBJID, + MH.MBOM_HEADER_OBJID, + MH.CHANGE_TYPE, + MH.CHANGE_DESCRIPTION, + MH.BEFORE_DATA, + MH.AFTER_DATA, + MH.CHANGE_USER, + TO_CHAR(MH.CHANGE_DATE, 'YYYY-MM-DD HH24:MI:SS') AS CHANGE_DATE, + -- MBOM_HEADER 정보 조인 + MHD.MBOM_NO AS MBOM_PART_NO, + MHD.PROJECT_OBJID, + TO_CHAR(MHD.REGDATE, 'YYYY-MM-DD HH24:MI:SS') AS REGDATE FROM - PART_BOM_REPORT PBR + MBOM_HISTORY MH + INNER JOIN MBOM_HEADER MHD ON MH.MBOM_HEADER_OBJID = MHD.OBJID WHERE - PBR.PART_NO = #{mbomPartNo} - ORDER BY PBR.REGDATE DESC + MHD.PROJECT_OBJID = #{projectObjId} + ORDER BY MH.CHANGE_DATE DESC - - - - SELECT REPLACE(UUID(),'-','') FROM DUAL - - INSERT INTO MBOM_HEADER ( - OBJID, - MBOM_NO, - PART_NO, - PART_NAME, - SAVE_DATE, - CREATE_USER, - CREATE_DATE, - UPDATE_USER, - UPDATE_DATE - ) VALUES ( - #{OBJID}, - CONCAT('MBOM-', DATE_FORMAT(NOW(), '%Y%m%d%H%i%s')), - #{PART_NO}, - #{PART_NAME}, - NOW(), - #{CREATE_USER}, - NOW(), - #{UPDATE_USER}, - NOW() - ) - - - - - - SELECT REPLACE(UUID(),'-','') FROM DUAL - - INSERT INTO MBOM_DETAIL ( - OBJID, - MBOM_HEADER_OBJID, - PART_NO, - PART_NAME, - QTY, - LEVEL, - REVISION, - SPEC, - PRODUCT_NAME, - STATUS_NAME, - CREATE_USER, - CREATE_DATE, - UPDATE_USER, - UPDATE_DATE - ) VALUES ( - #{OBJID}, - #{MBOM_HEADER_OBJID}, - #{PART_NO}, - #{PART_NAME}, - #{QTY}, - #{LEVEL}, - #{REVISION}, - #{SPEC}, - #{PRODUCT_NAME}, - #{STATUS_NAME}, - #{CREATE_USER}, - NOW(), - #{UPDATE_USER}, - NOW() - ) - - /* productionplanning.saveMbomFromEbom - E-BOM을 M-BOM으로 복사 */ @@ -3463,4 +3411,456 @@ PART_NAME = #{PART_NAME} WHERE OBJID::VARCHAR = #{PROJECT_OBJID} + + + + + + UPDATE PROJECT_MGMT + SET + SOURCE_BOM_TYPE = #{sourceBomType}, + SOURCE_EBOM_OBJID = CASE WHEN #{sourceBomType} = 'EBOM' THEN #{sourceBomObjId} ELSE NULL END, + SOURCE_MBOM_OBJID = CASE WHEN #{sourceBomType} = 'MBOM' THEN #{sourceBomObjId} ELSE NULL END + WHERE OBJID::VARCHAR = #{projectObjId} + + + + + + + + + + + + + + + + + INSERT INTO MBOM_HEADER ( + OBJID, MBOM_NO, SOURCE_BOM_TYPE, SOURCE_EBOM_OBJID, SOURCE_MBOM_OBJID, + PROJECT_OBJID, PART_NO, PART_NAME, STATUS, MBOM_STATUS, + WRITER, REGDATE + ) VALUES ( + #{objid}, #{mbomNo}, #{sourceBomType}, #{sourceEbomObjid}, #{sourceMbomObjid}, + #{projectObjId}, #{partNo}, #{partName}, 'Y', 'DRAFT', + #{sessionUserId}, NOW() + ) + + + + + INSERT INTO MBOM_DETAIL ( + OBJID, MBOM_HEADER_OBJID, PARENT_OBJID, CHILD_OBJID, SEQ, LEVEL, + PART_OBJID, PART_NO, PART_NAME, QTY, UNIT, + SUPPLY_TYPE, MAKE_OR_BUY, + RAW_MATERIAL_PART_NO, RAW_MATERIAL_SPEC, RAW_MATERIAL, RAW_MATERIAL_SIZE, + PROCESSING_VENDOR, PROCESSING_DEADLINE, GRINDING_DEADLINE, + REQUIRED_QTY, ORDER_QTY, PRODUCTION_QTY, STOCK_QTY, SHORTAGE_QTY, + VENDOR, UNIT_PRICE, TOTAL_PRICE, CURRENCY, LEAD_TIME, MIN_ORDER_QTY, + STATUS, WRITER, REGDATE, REMARK + ) VALUES ( + #{objid}, #{mbomHeaderObjid}, #{parentObjid}, #{childObjid}, #{seq}, #{level}, + #{partObjid}, #{partNo}, #{partName}, #{qty}, #{unit}, + #{supplyType}, #{makeOrBuy}, + #{rawMaterialPartNo}, #{rawMaterialSpec}, #{rawMaterial}, #{rawMaterialSize}, + #{processingVendor}, #{processingDeadline}, #{grindingDeadline}, + #{requiredQty}, #{orderQty}, #{productionQty}, #{stockQty}, #{shortageQty}, + #{vendor}, #{unitPrice}, #{totalPrice}, #{currency}, #{leadTime}, #{minOrderQty}, + 'ACTIVE', #{sessionUserId}, NOW(), #{remark} + ) + + + + + UPDATE MBOM_HEADER + SET + PART_NO = #{partNo}, + PART_NAME = #{partName}, + EDITER = #{sessionUserId}, + EDIT_DATE = NOW() + WHERE OBJID = #{mbomHeaderObjid} + + + + + DELETE FROM MBOM_DETAIL + WHERE MBOM_HEADER_OBJID = #{mbomHeaderObjid} + + + + + INSERT INTO MBOM_HISTORY ( + OBJID, MBOM_HEADER_OBJID, CHANGE_TYPE, CHANGE_DESCRIPTION, + BEFORE_DATA, AFTER_DATA, CHANGE_USER, CHANGE_DATE + ) VALUES ( + #{objid}, #{mbomHeaderObjid}, #{changeType}, #{changeDescription}, + #{beforeData}::JSONB, #{afterData}::JSONB, #{sessionUserId}, NOW() + ) + + + + + UPDATE PROJECT_MGMT + SET + MBOM_STATUS = 'Y', + MBOM_WRITER = #{sessionUserId}, + MBOM_REGDATE = NOW() + WHERE OBJID::VARCHAR = #{projectObjId} + + + + + + + + + + + + + + diff --git a/WebContent/WEB-INF/classes/com/pms/mapper/salesMng.xml b/WebContent/WEB-INF/classes/com/pms/mapper/salesMng.xml index 2547863..c74dadc 100644 --- a/WebContent/WEB-INF/classes/com/pms/mapper/salesMng.xml +++ b/WebContent/WEB-INF/classes/com/pms/mapper/salesMng.xml @@ -2773,5 +2773,127 @@ UPDATE SET ,QTY = #{QTY } ,NOTE = #{NOTE } + + + + + + INSERT INTO SALES_REQUEST_PART ( + OBJID, + SALES_REQUEST_MASTER_OBJID, + PART_NO, + PART_NAME, + QTY, + ITEM_QTY, + FILE_3D, + FILE_2D, + FILE_PDF, + MATERIAL, + HEAT_TREATMENT_HARDNESS, + HEAT_TREATMENT_METHOD, + SURFACE_TREATMENT, + SUPPLIER, + CATEGORY_NAME, + SUPPLY_TYPE, + RAW_MATERIAL, + SIZE, + RAW_MATERIAL_PART_NO, + RAW_MATERIAL_REQUIRED_QTY, + RAW_MATERIAL_ORDER_QTY, + ITEM_QTY2, + PRODUCTION_QTY, + PROCESSING_COMPANY, + PROCESSING_DELIVERY_DATE, + GRINDING_DELIVERY_DATE, + USE_YN, + NET_QTY, + ORDER_QTY, + SUPPLIER2, + UNIT_PRICE, + TOTAL_PRICE, + PROPOSAL_DATE, + WRITER, + REGDATE + ) VALUES ( + #{OBJID}, + #{SALES_REQUEST_MASTER_OBJID}, + #{PART_NO}, + #{PART_NAME}, + #{QTY}, + #{ITEM_QTY}, + #{FILE_3D}, + #{FILE_2D}, + #{FILE_PDF}, + #{MATERIAL}, + #{HEAT_TREATMENT_HARDNESS}, + #{HEAT_TREATMENT_METHOD}, + #{SURFACE_TREATMENT}, + #{SUPPLIER}, + #{CATEGORY_NAME}, + #{SUPPLY_TYPE}, + #{RAW_MATERIAL}, + #{SIZE}, + #{RAW_MATERIAL_PART_NO}, + #{RAW_MATERIAL_REQUIRED_QTY}, + #{RAW_MATERIAL_ORDER_QTY}, + #{ITEM_QTY2}, + #{PRODUCTION_QTY}, + #{PROCESSING_COMPANY}, + CASE WHEN #{PROCESSING_DELIVERY_DATE} = '' THEN NULL ELSE #{PROCESSING_DELIVERY_DATE}::date END, + CASE WHEN #{GRINDING_DELIVERY_DATE} = '' THEN NULL ELSE #{GRINDING_DELIVERY_DATE}::date END, + #{USE_YN}, + #{NET_QTY}, + #{ORDER_QTY}, + #{SUPPLIER2}, + #{UNIT_PRICE}, + #{TOTAL_PRICE}, + CASE WHEN #{PROPOSAL_DATE} = '' THEN NOW() ELSE #{PROPOSAL_DATE}::date END, + #{WRITER}, + NOW() + ) ON CONFLICT (OBJID) DO + UPDATE SET + ITEM_QTY = #{ITEM_QTY}, + FILE_3D = #{FILE_3D}, + FILE_2D = #{FILE_2D}, + FILE_PDF = #{FILE_PDF}, + MATERIAL = #{MATERIAL}, + HEAT_TREATMENT_HARDNESS = #{HEAT_TREATMENT_HARDNESS}, + HEAT_TREATMENT_METHOD = #{HEAT_TREATMENT_METHOD}, + SURFACE_TREATMENT = #{SURFACE_TREATMENT}, + SUPPLIER = #{SUPPLIER}, + CATEGORY_NAME = #{CATEGORY_NAME}, + SUPPLY_TYPE = #{SUPPLY_TYPE}, + RAW_MATERIAL = #{RAW_MATERIAL}, + SIZE = #{SIZE}, + RAW_MATERIAL_PART_NO = #{RAW_MATERIAL_PART_NO}, + RAW_MATERIAL_REQUIRED_QTY = #{RAW_MATERIAL_REQUIRED_QTY}, + RAW_MATERIAL_ORDER_QTY = #{RAW_MATERIAL_ORDER_QTY}, + ITEM_QTY2 = #{ITEM_QTY2}, + PRODUCTION_QTY = #{PRODUCTION_QTY}, + PROCESSING_COMPANY = #{PROCESSING_COMPANY}, + PROCESSING_DELIVERY_DATE = CASE WHEN #{PROCESSING_DELIVERY_DATE} = '' THEN NULL ELSE #{PROCESSING_DELIVERY_DATE}::date END, + GRINDING_DELIVERY_DATE = CASE WHEN #{GRINDING_DELIVERY_DATE} = '' THEN NULL ELSE #{GRINDING_DELIVERY_DATE}::date END, + USE_YN = #{USE_YN}, + NET_QTY = #{NET_QTY}, + ORDER_QTY = #{ORDER_QTY}, + SUPPLIER2 = #{SUPPLIER2}, + UNIT_PRICE = #{UNIT_PRICE}, + TOTAL_PRICE = #{TOTAL_PRICE} + \ No newline at end of file diff --git a/WebContent/WEB-INF/view/productionplanning/mBomMgmtList.jsp b/WebContent/WEB-INF/view/productionplanning/mBomMgmtList.jsp index d79f771..50070c9 100644 --- a/WebContent/WEB-INF/view/productionplanning/mBomMgmtList.jsp +++ b/WebContent/WEB-INF/view/productionplanning/mBomMgmtList.jsp @@ -39,6 +39,11 @@ $(document).ready(function(){ fn_openBomCopyPopup(); }); + // 구매리스트 생성 버튼 + $("#btnCreatePurchaseList").click(function(){ + fn_openPurchaseListPopup(); + }); + // 전체 체크박스 $(document).on('click', '#checkAll', function() { $('.rowCheck').prop('checked', $(this).prop('checked')); @@ -407,6 +412,44 @@ function fn_checkAssignmentAndOpenMbom(projectObjId) { } }); } + +// 구매리스트 생성 팝업 열기 +function fn_openPurchaseListPopup() { + // 체크된 행 가져오기 + var checkedRows = []; + $('.rowCheck:checked').each(function() { + var objid = $(this).data('objid'); + if(_tabulGrid && _tabulGrid.getRow) { + var rowData = _tabulGrid.getRow(objid).getData(); + checkedRows.push(rowData); + } + }); + + if(checkedRows.length == 0) { + Swal.fire({ + title: '알림', + text: '구매리스트를 생성할 프로젝트를 선택해주세요.', + icon: 'info' + }); + return; + } + + if(checkedRows.length > 1) { + Swal.fire({ + title: '알림', + text: '한 번에 하나의 프로젝트만 선택해주세요.', + icon: 'info' + }); + return; + } + + // 선택된 프로젝트의 OBJID + var projectObjId = checkedRows[0].OBJID; + + // 구매리스트 팝업 열기 + var url = "/salesMng/purchaseListFormPopUp.do?SALES_REQUEST_MASTER_OBJID=" + projectObjId; + window.open(url, "purchaseListPopup", "width=1400,height=800,scrollbars=yes,resizable=yes"); +} diff --git a/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp b/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp new file mode 100644 index 0000000..e1d6857 --- /dev/null +++ b/WebContent/WEB-INF/view/salesMng/purchaseListFormPopUp.jsp @@ -0,0 +1,407 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> +<%@ page import="com.pms.common.utils.*"%> +<%@ page import="java.util.*" %> +<%@include file="/init.jsp"%> + + + + + + +<%=Constants.SYSTEM_NAME%> + + + + +
+ + +
+
+

+ 구매리스트 작성 +

+
+ +
+
+ + + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NO품번품명수량항목수량3D2DPDF재료열처리경도열처리방법표면처리공급업체범주이름지급/사급소재사이즈소재품번소재소요량소재발주수량항목수량제작수량가공업체가공납기연삭납기사용여부정미수량발주수량공급업체단가총단가품의서작성일
+
+
+
+ + + diff --git a/database/add_purchase_list_columns_to_sales_request_part.sql b/database/add_purchase_list_columns_to_sales_request_part.sql new file mode 100644 index 0000000..3244e78 --- /dev/null +++ b/database/add_purchase_list_columns_to_sales_request_part.sql @@ -0,0 +1,63 @@ +-- SALES_REQUEST_PART 테이블에 구매리스트 관련 컬럼 추가 +-- 구매리스트 작성 시 필요한 추가 정보들 + +ALTER TABLE SALES_REQUEST_PART +ADD COLUMN IF NOT EXISTS ITEM_QTY VARCHAR(50), -- 항목수량 +ADD COLUMN IF NOT EXISTS FILE_3D VARCHAR(200), -- 3D +ADD COLUMN IF NOT EXISTS FILE_2D VARCHAR(200), -- 2D +ADD COLUMN IF NOT EXISTS FILE_PDF VARCHAR(200), -- PDF +ADD COLUMN IF NOT EXISTS MATERIAL VARCHAR(200), -- 재료 +ADD COLUMN IF NOT EXISTS HEAT_TREATMENT_HARDNESS VARCHAR(100), -- 열처리경도 +ADD COLUMN IF NOT EXISTS HEAT_TREATMENT_METHOD VARCHAR(100), -- 열처리방법 +ADD COLUMN IF NOT EXISTS SURFACE_TREATMENT VARCHAR(100), -- 표면처리 +ADD COLUMN IF NOT EXISTS SUPPLIER VARCHAR(200), -- 공급업체 +ADD COLUMN IF NOT EXISTS CATEGORY_NAME VARCHAR(100), -- 범주이름 +ADD COLUMN IF NOT EXISTS SUPPLY_TYPE VARCHAR(50), -- 지급/사급 +ADD COLUMN IF NOT EXISTS RAW_MATERIAL VARCHAR(200), -- 소재 +ADD COLUMN IF NOT EXISTS SIZE VARCHAR(100), -- 사이즈 +ADD COLUMN IF NOT EXISTS RAW_MATERIAL_PART_NO VARCHAR(100), -- 소재품번 +ADD COLUMN IF NOT EXISTS RAW_MATERIAL_REQUIRED_QTY VARCHAR(50), -- 소재소요량 +ADD COLUMN IF NOT EXISTS RAW_MATERIAL_ORDER_QTY VARCHAR(50), -- 소재발주수량 +ADD COLUMN IF NOT EXISTS ITEM_QTY2 VARCHAR(50), -- 항목수량 +ADD COLUMN IF NOT EXISTS PRODUCTION_QTY VARCHAR(50), -- 제작수량 +ADD COLUMN IF NOT EXISTS PROCESSING_COMPANY VARCHAR(200), -- 가공업체 +ADD COLUMN IF NOT EXISTS PROCESSING_DELIVERY_DATE DATE, -- 가공납기 +ADD COLUMN IF NOT EXISTS GRINDING_DELIVERY_DATE DATE, -- 연삭납기 +ADD COLUMN IF NOT EXISTS USE_YN VARCHAR(1) DEFAULT 'Y', -- 사용여부 +ADD COLUMN IF NOT EXISTS NET_QTY VARCHAR(50), -- 정미수량 +ADD COLUMN IF NOT EXISTS ORDER_QTY VARCHAR(50), -- 발주수량 +ADD COLUMN IF NOT EXISTS SUPPLIER2 VARCHAR(200), -- 공급업체 +ADD COLUMN IF NOT EXISTS UNIT_PRICE VARCHAR(50), -- 단가 +ADD COLUMN IF NOT EXISTS TOTAL_PRICE VARCHAR(50), -- 총단가 +ADD COLUMN IF NOT EXISTS PROPOSAL_DATE DATE; -- 품의서작성일 + +-- 컬럼 설명 +COMMENT ON COLUMN SALES_REQUEST_PART.ITEM_QTY IS '항목수량'; +COMMENT ON COLUMN SALES_REQUEST_PART.FILE_3D IS '3D'; +COMMENT ON COLUMN SALES_REQUEST_PART.FILE_2D IS '2D'; +COMMENT ON COLUMN SALES_REQUEST_PART.FILE_PDF IS 'PDF'; +COMMENT ON COLUMN SALES_REQUEST_PART.MATERIAL IS '재료'; +COMMENT ON COLUMN SALES_REQUEST_PART.HEAT_TREATMENT_HARDNESS IS '열처리경도'; +COMMENT ON COLUMN SALES_REQUEST_PART.HEAT_TREATMENT_METHOD IS '열처리방법'; +COMMENT ON COLUMN SALES_REQUEST_PART.SURFACE_TREATMENT IS '표면처리'; +COMMENT ON COLUMN SALES_REQUEST_PART.SUPPLIER IS '공급업체'; +COMMENT ON COLUMN SALES_REQUEST_PART.CATEGORY_NAME IS '범주이름'; +COMMENT ON COLUMN SALES_REQUEST_PART.SUPPLY_TYPE IS '지급/사급'; +COMMENT ON COLUMN SALES_REQUEST_PART.RAW_MATERIAL IS '소재'; +COMMENT ON COLUMN SALES_REQUEST_PART.SIZE IS '사이즈'; +COMMENT ON COLUMN SALES_REQUEST_PART.RAW_MATERIAL_PART_NO IS '소재품번'; +COMMENT ON COLUMN SALES_REQUEST_PART.RAW_MATERIAL_REQUIRED_QTY IS '소재소요량'; +COMMENT ON COLUMN SALES_REQUEST_PART.RAW_MATERIAL_ORDER_QTY IS '소재발주수량'; +COMMENT ON COLUMN SALES_REQUEST_PART.ITEM_QTY2 IS '항목수량'; +COMMENT ON COLUMN SALES_REQUEST_PART.PRODUCTION_QTY IS '제작수량'; +COMMENT ON COLUMN SALES_REQUEST_PART.PROCESSING_COMPANY IS '가공업체'; +COMMENT ON COLUMN SALES_REQUEST_PART.PROCESSING_DELIVERY_DATE IS '가공납기'; +COMMENT ON COLUMN SALES_REQUEST_PART.GRINDING_DELIVERY_DATE IS '연삭납기'; +COMMENT ON COLUMN SALES_REQUEST_PART.USE_YN IS '사용여부'; +COMMENT ON COLUMN SALES_REQUEST_PART.NET_QTY IS '정미수량'; +COMMENT ON COLUMN SALES_REQUEST_PART.ORDER_QTY IS '발주수량'; +COMMENT ON COLUMN SALES_REQUEST_PART.SUPPLIER2 IS '공급업체'; +COMMENT ON COLUMN SALES_REQUEST_PART.UNIT_PRICE IS '단가'; +COMMENT ON COLUMN SALES_REQUEST_PART.TOTAL_PRICE IS '총단가'; +COMMENT ON COLUMN SALES_REQUEST_PART.PROPOSAL_DATE IS '품의서작성일'; + diff --git a/database/create_purchase_list_table.sql b/database/create_purchase_list_table.sql new file mode 100644 index 0000000..244e6ec --- /dev/null +++ b/database/create_purchase_list_table.sql @@ -0,0 +1,80 @@ +-- 구매리스트 테이블 생성 +CREATE TABLE IF NOT EXISTS PURCHASE_LIST ( + OBJID VARCHAR(50) PRIMARY KEY, + SALES_REQUEST_MASTER_OBJID VARCHAR(50), + PART_NO VARCHAR(100), + PART_NAME VARCHAR(200), + QTY VARCHAR(50), + ITEM_QTY VARCHAR(50), + FILE_3D VARCHAR(200), + FILE_2D VARCHAR(200), + FILE_PDF VARCHAR(200), + MATERIAL VARCHAR(200), + HEAT_TREATMENT_HARDNESS VARCHAR(100), + HEAT_TREATMENT_METHOD VARCHAR(100), + SURFACE_TREATMENT VARCHAR(100), + SUPPLIER VARCHAR(200), + CATEGORY_NAME VARCHAR(100), + SUPPLY_TYPE VARCHAR(50), + RAW_MATERIAL VARCHAR(200), + SIZE VARCHAR(100), + RAW_MATERIAL_PART_NO VARCHAR(100), + RAW_MATERIAL_REQUIRED_QTY VARCHAR(50), + RAW_MATERIAL_ORDER_QTY VARCHAR(50), + ITEM_QTY2 VARCHAR(50), + PRODUCTION_QTY VARCHAR(50), + PROCESSING_COMPANY VARCHAR(200), + PROCESSING_DELIVERY_DATE DATE, + GRINDING_DELIVERY_DATE DATE, + USE_YN VARCHAR(1) DEFAULT 'Y', + NET_QTY VARCHAR(50), + ORDER_QTY VARCHAR(50), + SUPPLIER2 VARCHAR(200), + UNIT_PRICE VARCHAR(50), + TOTAL_PRICE VARCHAR(50), + PROPOSAL_DATE DATE, + WRITER VARCHAR(50), + REGDATE TIMESTAMP DEFAULT NOW() +); + +-- 인덱스 생성 +CREATE INDEX IF NOT EXISTS idx_purchase_list_sales_request ON PURCHASE_LIST(SALES_REQUEST_MASTER_OBJID); + +-- 컬럼 설명 +COMMENT ON TABLE PURCHASE_LIST IS '구매리스트'; +COMMENT ON COLUMN PURCHASE_LIST.OBJID IS 'OBJID'; +COMMENT ON COLUMN PURCHASE_LIST.SALES_REQUEST_MASTER_OBJID IS '구매요청서 OBJID'; +COMMENT ON COLUMN PURCHASE_LIST.PART_NO IS '품번'; +COMMENT ON COLUMN PURCHASE_LIST.PART_NAME IS '품명'; +COMMENT ON COLUMN PURCHASE_LIST.QTY IS '수량'; +COMMENT ON COLUMN PURCHASE_LIST.ITEM_QTY IS '항목수량'; +COMMENT ON COLUMN PURCHASE_LIST.FILE_3D IS '3D'; +COMMENT ON COLUMN PURCHASE_LIST.FILE_2D IS '2D'; +COMMENT ON COLUMN PURCHASE_LIST.FILE_PDF IS 'PDF'; +COMMENT ON COLUMN PURCHASE_LIST.MATERIAL IS '재료'; +COMMENT ON COLUMN PURCHASE_LIST.HEAT_TREATMENT_HARDNESS IS '열처리경도'; +COMMENT ON COLUMN PURCHASE_LIST.HEAT_TREATMENT_METHOD IS '열처리방법'; +COMMENT ON COLUMN PURCHASE_LIST.SURFACE_TREATMENT IS '표면처리'; +COMMENT ON COLUMN PURCHASE_LIST.SUPPLIER IS '공급업체'; +COMMENT ON COLUMN PURCHASE_LIST.CATEGORY_NAME IS '범주이름'; +COMMENT ON COLUMN PURCHASE_LIST.SUPPLY_TYPE IS '지급/사급'; +COMMENT ON COLUMN PURCHASE_LIST.RAW_MATERIAL IS '소재'; +COMMENT ON COLUMN PURCHASE_LIST.SIZE IS '사이즈'; +COMMENT ON COLUMN PURCHASE_LIST.RAW_MATERIAL_PART_NO IS '소재품번'; +COMMENT ON COLUMN PURCHASE_LIST.RAW_MATERIAL_REQUIRED_QTY IS '소재소요량'; +COMMENT ON COLUMN PURCHASE_LIST.RAW_MATERIAL_ORDER_QTY IS '소재발주수량'; +COMMENT ON COLUMN PURCHASE_LIST.ITEM_QTY2 IS '항목수량'; +COMMENT ON COLUMN PURCHASE_LIST.PRODUCTION_QTY IS '제작수량'; +COMMENT ON COLUMN PURCHASE_LIST.PROCESSING_COMPANY IS '가공업체'; +COMMENT ON COLUMN PURCHASE_LIST.PROCESSING_DELIVERY_DATE IS '가공납기'; +COMMENT ON COLUMN PURCHASE_LIST.GRINDING_DELIVERY_DATE IS '연삭납기'; +COMMENT ON COLUMN PURCHASE_LIST.USE_YN IS '사용여부'; +COMMENT ON COLUMN PURCHASE_LIST.NET_QTY IS '정미수량'; +COMMENT ON COLUMN PURCHASE_LIST.ORDER_QTY IS '발주수량'; +COMMENT ON COLUMN PURCHASE_LIST.SUPPLIER2 IS '공급업체'; +COMMENT ON COLUMN PURCHASE_LIST.UNIT_PRICE IS '단가'; +COMMENT ON COLUMN PURCHASE_LIST.TOTAL_PRICE IS '총단가'; +COMMENT ON COLUMN PURCHASE_LIST.PROPOSAL_DATE IS '품의서작성일'; +COMMENT ON COLUMN PURCHASE_LIST.WRITER IS '작성자'; +COMMENT ON COLUMN PURCHASE_LIST.REGDATE IS '등록일'; + diff --git a/src/com/pms/mapper/salesMng.xml b/src/com/pms/mapper/salesMng.xml index 2547863..c74dadc 100644 --- a/src/com/pms/mapper/salesMng.xml +++ b/src/com/pms/mapper/salesMng.xml @@ -2773,5 +2773,127 @@ UPDATE SET ,QTY = #{QTY } ,NOTE = #{NOTE } + + + + + + INSERT INTO SALES_REQUEST_PART ( + OBJID, + SALES_REQUEST_MASTER_OBJID, + PART_NO, + PART_NAME, + QTY, + ITEM_QTY, + FILE_3D, + FILE_2D, + FILE_PDF, + MATERIAL, + HEAT_TREATMENT_HARDNESS, + HEAT_TREATMENT_METHOD, + SURFACE_TREATMENT, + SUPPLIER, + CATEGORY_NAME, + SUPPLY_TYPE, + RAW_MATERIAL, + SIZE, + RAW_MATERIAL_PART_NO, + RAW_MATERIAL_REQUIRED_QTY, + RAW_MATERIAL_ORDER_QTY, + ITEM_QTY2, + PRODUCTION_QTY, + PROCESSING_COMPANY, + PROCESSING_DELIVERY_DATE, + GRINDING_DELIVERY_DATE, + USE_YN, + NET_QTY, + ORDER_QTY, + SUPPLIER2, + UNIT_PRICE, + TOTAL_PRICE, + PROPOSAL_DATE, + WRITER, + REGDATE + ) VALUES ( + #{OBJID}, + #{SALES_REQUEST_MASTER_OBJID}, + #{PART_NO}, + #{PART_NAME}, + #{QTY}, + #{ITEM_QTY}, + #{FILE_3D}, + #{FILE_2D}, + #{FILE_PDF}, + #{MATERIAL}, + #{HEAT_TREATMENT_HARDNESS}, + #{HEAT_TREATMENT_METHOD}, + #{SURFACE_TREATMENT}, + #{SUPPLIER}, + #{CATEGORY_NAME}, + #{SUPPLY_TYPE}, + #{RAW_MATERIAL}, + #{SIZE}, + #{RAW_MATERIAL_PART_NO}, + #{RAW_MATERIAL_REQUIRED_QTY}, + #{RAW_MATERIAL_ORDER_QTY}, + #{ITEM_QTY2}, + #{PRODUCTION_QTY}, + #{PROCESSING_COMPANY}, + CASE WHEN #{PROCESSING_DELIVERY_DATE} = '' THEN NULL ELSE #{PROCESSING_DELIVERY_DATE}::date END, + CASE WHEN #{GRINDING_DELIVERY_DATE} = '' THEN NULL ELSE #{GRINDING_DELIVERY_DATE}::date END, + #{USE_YN}, + #{NET_QTY}, + #{ORDER_QTY}, + #{SUPPLIER2}, + #{UNIT_PRICE}, + #{TOTAL_PRICE}, + CASE WHEN #{PROPOSAL_DATE} = '' THEN NOW() ELSE #{PROPOSAL_DATE}::date END, + #{WRITER}, + NOW() + ) ON CONFLICT (OBJID) DO + UPDATE SET + ITEM_QTY = #{ITEM_QTY}, + FILE_3D = #{FILE_3D}, + FILE_2D = #{FILE_2D}, + FILE_PDF = #{FILE_PDF}, + MATERIAL = #{MATERIAL}, + HEAT_TREATMENT_HARDNESS = #{HEAT_TREATMENT_HARDNESS}, + HEAT_TREATMENT_METHOD = #{HEAT_TREATMENT_METHOD}, + SURFACE_TREATMENT = #{SURFACE_TREATMENT}, + SUPPLIER = #{SUPPLIER}, + CATEGORY_NAME = #{CATEGORY_NAME}, + SUPPLY_TYPE = #{SUPPLY_TYPE}, + RAW_MATERIAL = #{RAW_MATERIAL}, + SIZE = #{SIZE}, + RAW_MATERIAL_PART_NO = #{RAW_MATERIAL_PART_NO}, + RAW_MATERIAL_REQUIRED_QTY = #{RAW_MATERIAL_REQUIRED_QTY}, + RAW_MATERIAL_ORDER_QTY = #{RAW_MATERIAL_ORDER_QTY}, + ITEM_QTY2 = #{ITEM_QTY2}, + PRODUCTION_QTY = #{PRODUCTION_QTY}, + PROCESSING_COMPANY = #{PROCESSING_COMPANY}, + PROCESSING_DELIVERY_DATE = CASE WHEN #{PROCESSING_DELIVERY_DATE} = '' THEN NULL ELSE #{PROCESSING_DELIVERY_DATE}::date END, + GRINDING_DELIVERY_DATE = CASE WHEN #{GRINDING_DELIVERY_DATE} = '' THEN NULL ELSE #{GRINDING_DELIVERY_DATE}::date END, + USE_YN = #{USE_YN}, + NET_QTY = #{NET_QTY}, + ORDER_QTY = #{ORDER_QTY}, + SUPPLIER2 = #{SUPPLIER2}, + UNIT_PRICE = #{UNIT_PRICE}, + TOTAL_PRICE = #{TOTAL_PRICE} + \ No newline at end of file diff --git a/src/com/pms/salesmgmt/controller/SalesMngController.java b/src/com/pms/salesmgmt/controller/SalesMngController.java index 18a545a..30de9b2 100644 --- a/src/com/pms/salesmgmt/controller/SalesMngController.java +++ b/src/com/pms/salesmgmt/controller/SalesMngController.java @@ -1086,4 +1086,53 @@ public class SalesMngController { } return resultMap; } + + /** + * 구매리스트 작성 팝업 + * @param request + * @param paramMap + * @return + */ + @RequestMapping("/salesMng/purchaseListFormPopUp.do") + public String purchaseListFormPopUp(HttpServletRequest request, @RequestParam Map paramMap){ + return "/salesMng/purchaseListFormPopUp"; + } + + /** + * 구매리스트 데이터 조회 + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/getPurchaseListData.do") + public Map getPurchaseListData(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + try{ + resultMap = salesMngService.getPurchaseListData(request, paramMap); + }catch(Exception e){ + e.printStackTrace(); + } + return resultMap; + } + + /** + * 구매리스트 저장 + * @param request + * @param paramMap + * @return + */ + @ResponseBody + @RequestMapping("/salesMng/savePurchaseList.do") + public Map savePurchaseList(HttpServletRequest request, @RequestParam Map paramMap){ + Map resultMap = new HashMap(); + try{ + resultMap = salesMngService.savePurchaseList(request, paramMap); + }catch(Exception e){ + e.printStackTrace(); + resultMap.put("result", "error"); + resultMap.put("message", "저장 중 오류가 발생했습니다: " + e.getMessage()); + } + return resultMap; + } } diff --git a/src/com/pms/salesmgmt/service/SalesMngService.java b/src/com/pms/salesmgmt/service/SalesMngService.java index 4c74bfb..1a20022 100644 --- a/src/com/pms/salesmgmt/service/SalesMngService.java +++ b/src/com/pms/salesmgmt/service/SalesMngService.java @@ -1694,4 +1694,95 @@ public class SalesMngService { return resultMap; } + + /** + * 구매리스트 데이터 조회 + * @param request + * @param paramMap + * @return + */ + public Map getPurchaseListData(HttpServletRequest request, Map paramMap) { + Map resultMap = new HashMap(); + SqlSession sqlSession = null; + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(false); + String salesRequestMasterObjid = CommonUtils.checkNull(paramMap.get("SALES_REQUEST_MASTER_OBJID")); + + // SALES_REQUEST_PART 조회 + List partList = sqlSession.selectList("salesMng.getSalesRequestPartList", salesRequestMasterObjid); + + resultMap.put("partList", partList); + + } catch(Exception e) { + e.printStackTrace(); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } + + /** + * 구매리스트 저장 + * @param request + * @param paramMap + * @return + */ + public Map savePurchaseList(HttpServletRequest request, Map paramMap) { + Map resultMap = new HashMap(); + SqlSession sqlSession = null; + + try { + sqlSession = SqlMapConfig.getInstance().getSqlSession(false); + String salesRequestMasterObjid = CommonUtils.checkNull(paramMap.get("SALES_REQUEST_MASTER_OBJID")); + String partListJson = CommonUtils.checkNull(paramMap.get("partList")); + + // JSON 파싱 - 기존 코드 참고하여 간단하게 처리 + // partListJson이 이미 파싱된 상태일 수 있으므로 직접 처리 + List partList = new ArrayList(); + // TODO: JSON 파싱 로직 추가 필요 + + if(partList == null || partList.isEmpty()) { + resultMap.put("result", "error"); + resultMap.put("message", "저장할 데이터가 없습니다."); + return resultMap; + } + + // 로그인 사용자 정보 + HttpSession session = request.getSession(); + PersonBean personBean = (PersonBean) session.getAttribute(Constants.PERSON_BEAN); + String userId = personBean.getUserId(); + + // 각 품목별로 구매리스트 정보 저장 + for(Map partData : partList) { + String objid = CommonUtils.checkNull(partData.get("OBJID")); + + if(objid.isEmpty()) { + objid = CommonUtils.createObjId(); + } + + partData.put("OBJID", objid); + partData.put("SALES_REQUEST_MASTER_OBJID", salesRequestMasterObjid); + partData.put("WRITER", userId); + + // SALES_REQUEST_PART 테이블에 저장 + sqlSession.insert("salesMng.mergePurchaseListInfo", partData); + } + + resultMap.put("result", "success"); + resultMap.put("message", "저장되었습니다."); + sqlSession.commit(); + + } catch(Exception e) { + if(sqlSession != null) sqlSession.rollback(); + resultMap.put("result", "error"); + resultMap.put("message", "저장 중 오류가 발생했습니다: " + e.getMessage()); + e.printStackTrace(); + } finally { + if(sqlSession != null) sqlSession.close(); + } + + return resultMap; + } }