21cd81bd79
sales/README.md 패턴 따라 생산관리 도메인 전체 문서화: - 정책: 5개 메뉴(M-BOM/계획실적×2/소요량×2)가 전부, vexplor 잔재(bom/plan-management/process-info/result/work-instruction) 제외 - 메뉴 매핑표 + 도메인 테이블 + data-sync/ddl-extracted 인덱스 - productionplanning.xml 23개 매퍼 → mbomService/prodPlanResultService/mbomRequirementService 1:1 표 - PR-A0~B5+ 진행 흐름 + 대표 커밋 - 5메뉴 1:1 검증 결과(Agent 5병렬, 2026-05-15) - PR-B5+ BOM 복사 다이얼로그 상세 (BomCopyDialog, 도면업로드 차이 명시) - 다음 작업 후보 6종 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
14 KiB
14 KiB
생산관리 이식 (wace_plm → vexplor_rps)
작성: 2026-05-15 / 작성자: hjjeong 대상: vexplor_rps (RPS 전용 분기, COMPANY_16 단독 운영) 원본: wace_plm (Java 7 / Spring 3.2.4 / JSP / MyBatis)
0. 정책 (사용자 확정 사항)
- 이식 방식: JSP → Next.js 리라이트 (백엔드도 Java→Node 재작성, vexplor_rps
backend-node패턴) - 스키마 정책: wace_plm 도메인 테이블(
mbom_header/mbom_detail/mbom_history/sales_request_master/project_mgmt/contract_mgmt/part_bom_report등) 그대로 이식. 마스터(customer_mng/item_info/user_info등)는 RPS 기존 사용. - 이식 대상 메뉴 = 5개 (2026-05-15 사용자 확정):
- M-BOM 관리 (
/productionplanning/mBomMgmtList.do) - 생산계획&실적관리 (
/productionplanning/prodPlanResultMgmtList.do) - 생산계획&실적관리(장비) (
/productionplanning/prodPlanResultMgmtEquipList.do) - 반제품소요량 (
/productionplanning/semiProductRequirementList.do) - 원자재소요량 (
/productionplanning/rawMaterialRequirementList.do)
- M-BOM 관리 (
- ⚠️
production/{bom,plan-management,process-info,result,work-instruction}디렉토리는 vexplor 잔재 — wace_plm 매뉴얼 5개에 없음, 이식 대상 아님. - 메뉴 노출: M-BOM 관리는 생산관리 + 구매관리 트리 양쪽 진입 허용 (
menu_info100016 + 100032 동시 활성). 구매관리 페이지는 production/mbom re-export.
1. 메뉴 매핑표
| # | 메뉴명 | wace_plm URL | wace_plm JSP | wace_plm Controller | RPS 신규 위치 |
|---|---|---|---|---|---|
| 1 | M-BOM 관리 | /productionplanning/mBomMgmtList.do |
productionplanning/mBomMgmtList.jsp |
ProductionPlanningController |
app/(main)/COMPANY_16/production/mbom/page.tsx + backend-node/src/{routes,services,controllers}/mbom* (PR-A0~B5+) |
| 2 | 생산계획&실적관리 | /productionplanning/prodPlanResultMgmtList.do |
productionplanning/prodPlanResultMgmtList.jsp |
ProductionPlanningController |
app/(main)/COMPANY_16/production/plan-result/page.tsx + backend-node/src/{routes,services,controllers}/prodPlanResult* |
| 3 | 생산계획&실적관리(장비) | /productionplanning/prodPlanResultMgmtEquipList.do |
productionplanning/prodPlanResultMgmtEquipList.jsp |
ProductionPlanningController |
app/(main)/COMPANY_16/production/plan-result-equip/page.tsx + 위와 동일 service (listEquip 분기) |
| 4 | 반제품소요량 | /productionplanning/semiProductRequirementList.do |
productionplanning/semiProductRequirementList.jsp |
ProductionPlanningController |
app/(main)/COMPANY_16/production/semi-product-req/page.tsx + backend-node/src/services/mbomRequirementService.ts (listSemi) |
| 5 | 원자재소요량 | /productionplanning/rawMaterialRequirementList.do |
productionplanning/rawMaterialRequirementList.jsp |
ProductionPlanningController |
app/(main)/COMPANY_16/production/raw-material-req/page.tsx + 위와 동일 service (listRaw) |
| ─ | BOM 복사 다이얼로그 (M-BOM 보조) | /partMng/structureBomCopyFormPopup.do |
partMng/structureBomCopyFormPopup.jsp |
PartMngController |
components/production/BomCopyDialog.tsx (PR-B5+) |
2. 도메인 테이블
이식 대상 — RPS DB에 CREATE 그대로 적용. DDL은 ddl-extracted/, 동기화 SQL은 data-sync/.
| 우선순위 | 테이블 | 용도 | DDL 파일 |
|---|---|---|---|
| ★★★ | mbom_header |
M-BOM 헤더 (project_objid 별 1+ 버전, status='Y' 가 활성) | 400_mbom.sql |
| ★★★ | mbom_detail |
M-BOM 상세 (parent/child 트리, qty/required_qty/order_qty/production_qty) | 400_mbom.sql |
| ★★★ | mbom_history |
M-BOM 변경이력 (CHANGE_TYPE = CREATE/UPDATE) | 401_mbom_dependencies.sql |
| ★★★ | sales_request_master |
구매리스트(R-YYYYMMDD-NNN), M-BOM 으로부터 단건 생성 | 401_mbom_dependencies.sql |
| ★★★ | project_mgmt |
프로젝트 헤더 (source_bom_type/source_ebom_objid/source_mbom_objid) | (sales 도메인 기존 테이블 재사용) |
| ★★★ | contract_mgmt / contract_item |
수주/계약 정보 (product != '0000928' = Machine 외 판별) | (sales 도메인 기존 테이블 재사용) |
| ★★ | part_bom_report / bom_part_qty |
E-BOM 참조 (BOM 할당/복사 소스) | (개발관리 도메인 기존 테이블) |
| ★★ | production_plan |
생산계획(plan-result 보조) | 402_production_plan.sql |
| ★ | attach_file_info |
도면 다중 업로드 (PR-B5+ BomCopyDialog, doc_type='MBOM_DRAWING') | (공용 테이블) |
| ★ | client_mng |
고객사 (user_name() fn 동반) |
(sales 기존) |
데이터 동기화 SQL (data-sync/)
| 파일 | 용도 |
|---|---|
01_mbom_sync.sql |
운영 DB → RPS mbom_header/detail 데이터 이주 |
02_mbom_dependencies_sync.sql |
mbom_history + sales_request_master 동기화 |
03_mbom_menu_dedup.sql |
menu_info 중복 정리 (M-BOM 100016/100032) |
04_production_plan_sync.sql |
production_plan 동기화 |
05_mbom_menu_desc.sql |
M-BOM 관리 메뉴명 sync |
3. 매퍼 매핑표 (productionplanning.xml 1:1)
| wace 매퍼 ID | wace 라인 | RPS 함수 (mbomService) | PR |
|---|---|---|---|
mBomMgmtGridList |
2874-3119 | list() |
A1 |
getProjectMgmtDetail |
3150-3218 | getDetail() |
A2 |
getLatestMbomByProjectId |
3555-3570 | getLatestSavedMbom() |
A2 |
getLatestMbomTemplateByPartNo |
3573-3591 | getLatestTemplate() |
A2 |
getMbomTemplateDetails |
3594-3794 | getTemplateDetails() |
A2 |
getSavedMbomTreeList |
4114-4359 | getSavedTree() |
A2 |
getMbomStructureOnly |
4362-4538 | getStructureOnly() |
A2 |
insertMbomHeader/Detail |
3873/3886 | save() CREATE |
B1 |
updateMbomHeader/Detail |
3917/3940 | save() UPDATE |
B1 |
deleteMbomDetailByObjid |
3934 | save() UPDATE 누락 행 |
B1 |
insertMbomHistory |
3973 | insertHistory() helper |
B1/B4 |
updateProjectMbomStatus |
3949 | save() CREATE |
B1 |
getMbomHistory |
3448-3470 | getHistory() |
B4 |
partMng.getBOMTreeList |
partMng.xml 3289-3549 | getEbomWorkingTree() / previewEbomTree() |
A2/B5 |
getEbomList |
3221-3265 | searchAssignableEboms() |
B5 |
saveBomAssignment |
3545-3553 | assignBom() (EBOM/MBOM 둘 다) |
B5 |
getLatestMbomByPartNo |
3426-3445 | getLatestMbomByPartNo() |
B5+ |
getMbomListForSelect2 |
4007-4014 | searchAssignableMboms() |
B5+ |
salesMng.insertSalesRequestMasterFromMBom |
~3975 | createSalesRequest() |
B3 |
prodPlanResultMgmtGridList |
4550~ | prodPlanResultService.listGeneral() |
— |
prodPlanResultMgmtEquipGridList |
4887~ | prodPlanResultService.listEquip() |
— |
semiProductRequirementList (Java LinkedHashMap) |
~5252 | mbomRequirementService.listSemi() |
— |
rawMaterialRequirementList (Java LinkedHashMap) |
— | mbomRequirementService.listRaw() |
— |
4. PR 진행 흐름
| PR | 내용 | 대표 커밋 |
|---|---|---|
| A0 | 의존 테이블 (mbom_history/sales_request_master/client_mng + user_name fn) | 7af366c5 |
| A0' | M-BOM 테이블 신설 (mbom_header/detail + 운영 sample) | 04cfac6e |
| A1 | 메인 그리드/검색 (mBomMgmtGridList 1:1) | 66cee22b |
| A2 | 단건 상세 + read-only 트리 4분기 (SAVED/ASSIGNED_EBOM/ASSIGNED_MBOM/TEMPLATE/NONE) | dd88dc6e |
| B1 | 본 편집 + 폴더 컬럼 + DataGrid 서버 페이지네이션 + bigint=varchar fix | 7a7f4f03 |
| B2 | 본 편집 행 추가/삭제 (팝업 방식, MbomAddPartDialog, temp-objid remap) | dee03f60 |
| B3 | 구매리스트 생성 (createPurchaseListFromMBom 1:1) | b38f5957 |
| B4 | 변경이력 다이얼로그 (getMbomHistory 1:1) | 8dd5f184 |
| B5 | BOM 할당 베이스 (mBomEbomSelectPopup 진입점) | b38f5957 |
| B5 | BOM 할당 운영판 1:1 재구성 (카드+토글+미리보기 트리+제품구분/날짜 검색) | bd47ca80 |
| 보정 | 4개 메뉴 디렉토리 rename(URL 일치) + 그리드 헤더 보정 + 소요량 numeric 캐스팅 fix | c83a73a1 |
| B5+ | BOM 복사 다이얼로그 (structureBomCopyFormPopup 1:1) + 5메뉴 1:1 검증 | 63682587 |
5. 5개 메뉴 1:1 검증 결과 (2026-05-15)
Agent 5병렬 (read-only) 검증.
| 메뉴 | 판정 | 비고 |
|---|---|---|
| M-BOM 관리 | PASS (B5+ 후) | 검색 폼 / 그리드 16컬럼 / SQL 100% 일치. 품번/품명만 wace Select2-part(AJAX) → Input text. B5+ 로 누락된 [BOM 복사] 보완. |
| 생산계획&실적관리 | MINOR_DIFF | 검색 13필드 / 그리드 18컬럼 / SQL 100% 일치. [생산계획 생성]·[생산실적 등록] 액션 모달은 미구현(프로토타입). 품번/품명 Select2-part → Input text. |
| 생산계획&실적관리(장비) | PASS | 검색 9필드 / 그리드 14컬럼 / SQL 100% 일치. WBS할당 모달은 의도적 미구현 (주석 명시). |
| 반제품소요량 | MINOR_DIFF | 입력 폼 / 결과 4컬럼 / SQL / 누적 로직 100% 일치. RPS만 단위/소재/규격 3컬럼 추가 노출 (UX 향상). c83a73a1 에서 numeric 캐스팅 fix. |
| 원자재소요량 | PASS | 입력 / 8컬럼 / 구매품·원소재 SQL / Math.ceil 누적 / 숫자 포맷 모두 100% 일치. |
6. PR-B5+ BOM 복사 다이얼로그 (2026-05-15)
운영판 partMng/structureBomCopyFormPopup.jsp (774 lines) 1:1.
진입: 메인 그리드 [BOM 복사] 버튼 — 체크박스 단건 선택 + Machine(0000928) 외 동일 partNo 매칭 시 기존 M-BOM 자동 추천(getLatestMbomByPartNo 호출).
레이아웃:
- 상단: 품번 / 품명 readonly + [저장] [닫기]
- 중단: E-BOM 셀렉트 / M-BOM 셀렉트 (상호배타, 한쪽 선택 시 다른쪽 disable)
- 하단: 트리 미리보기 + 도면 다중 업로드 (공용
AttachFileDropZone, target=projectObjid, docType=MBOM_DRAWING, accept=.stp,.step,.dwg,.dxf,.pdf)
저장: assignBom 재사용 (PR-B5 매퍼 saveBomAssignment 1:1). 백엔드는 EBOM/MBOM 분기 이미 지원, 이번에 MBOM UI 진입점도 첫 노출.
도면 업로드 차이: 운영판 fn_uploadDrawingFiles는 placeholder ("구현 예정" 토스트). RPS는 공용 AttachFileDropZone 재사용해 wace 보다 앞서 실구현.
신규 산출물:
| 위치 | 역할 |
|---|---|
backend-node/src/services/mbomService.ts |
searchAssignableMboms / previewMbomTree / getLatestMbomByPartNo 3 함수 |
backend-node/src/controllers/mbomController.ts |
3 핸들러 추가 |
backend-node/src/routes/productionMbomRoutes.ts |
GET /assignable-mboms, GET /mbom-preview/:objid, GET /latest-mbom-by-partno/:partNo |
frontend/lib/api/mbom.ts |
3 메서드 + AssignableMbomRow / LatestMbomByPartNoRow 타입 |
frontend/components/production/BomCopyDialog.tsx |
신규 다이얼로그 |
frontend/app/(main)/COMPANY_16/production/mbom/page.tsx |
[BOM 복사] 버튼 + Dialog 연결 |
7. 백엔드 산출물 (backend-node/src/)
| 파일 | 역할 |
|---|---|
services/mbomService.ts |
list / getDetail / getTree(4분기) / save / getHistory / searchAssignableEboms / previewEbomTree / assignBom / searchAssignableMboms / previewMbomTree / getLatestMbomByPartNo / createSalesRequest |
controllers/mbomController.ts |
위 모든 핸들러 |
routes/productionMbomRoutes.ts |
위 모든 라우트 |
services/prodPlanResultService.ts |
listGeneral (plan-result) + listEquip (plan-result-equip), buildWhere 공유 |
controllers/prodPlanResultController.ts |
위 2 핸들러 |
routes/productionPlanResultRoutes.ts |
GET /list, GET /equip/list |
services/mbomRequirementService.ts |
listSemi (반제품) + listRaw (원자재), getOptions (M-BOM 셀렉트 + 품명) |
8. 프론트엔드 산출물 (frontend/)
| 파일 | 역할 |
|---|---|
lib/api/mbom.ts |
타입 + mbomApi 14 메서드 |
lib/api/prodPlanResult.ts |
일반/장비 list 타입 |
components/production/MbomDetailDialog.tsx |
단건 상세 + 트리 + 편집 + toolbar(변경이력/BOM 할당/본 편집/행 add-del) |
components/production/MbomHistoryDialog.tsx |
변경이력 그리드 |
components/production/MbomAddPartDialog.tsx |
행 추가 시 PART 검색 |
components/production/MbomAssignDialog.tsx |
BOM 할당 (운영 mBomEbomSelectPopup 1:1) |
components/production/BomCopyDialog.tsx |
BOM 복사 (PR-B5+ 신규) |
app/(main)/COMPANY_16/production/mbom/page.tsx |
메인 리스트 + 폴더 컬럼 + 서버 페이지네이션 + [구매리스트 생성] + [BOM 복사] |
app/(main)/COMPANY_16/purchase/mbom/page.tsx |
re-export (구매관리 트리 노출) |
app/(main)/COMPANY_16/production/plan-result/page.tsx |
생산계획&실적 |
app/(main)/COMPANY_16/production/plan-result-equip/page.tsx |
장비 |
app/(main)/COMPANY_16/production/semi-product-req/page.tsx |
반제품 소요량 |
app/(main)/COMPANY_16/production/raw-material-req/page.tsx |
원자재 소요량 |
9. 작업 원칙 (도메인 공통)
- 운영판 1:1 정확 일치 —
waceplm.esgrin.com진실의 기준 - JSP/매퍼/Java
/* */·<!-- -->·//비활성 보존 — 이식 대상 아님 - bigint=varchar 함정:
ATTACH_FILE_INFO서브쿼리는P.OBJID::varchar = F.TARGET_OBJID캐스트 필수 - numeric 캐스팅: RPS
mbom_detail.qty/required_qty는numeric(15,4). wace 의NULLIF(x,'')::INTEGER패턴 적용 시 "invalid input syntax" 발생 →COALESCE(x, 0)::INTEGER패턴 사용 (c83a73a1) - 메뉴 등록은 menu_info 직접 UPDATE (data-sync 스크립트 동반)
- 다른 세션 작업물은 따로 커밋 — working tree 에 보여도 묶지 말 것
- 공용 컴포넌트 의무: PageHeader + CompactFilterBar + SmartSelect/CustomerSelect + DataGrid
10. 다음 작업 후보
- plan-result 액션 모달 — 생산계획 생성 / 생산실적 등록 1:1 이식
- 공통 PartSelect 컴포넌트 — wace
Select2-part(AJAX 자동완성) 복원, 4개 메뉴 공통 적용 - PR-B6 — Excel Upload/Download (운영판 mBomFormPopup 의 Excel 버튼 2종)
- PR-B7 — 행 순서 변경 (up/down) + 부모 변경 (drag drop)
- 품질관리 후속 — chpark 가 베이스만 짠 4개 메뉴(incoming/process/semi-product inspection) 상세화 (별 PR)
- 자재관리 도메인 진입 — 별 PR