# 01. 진행관리 이식 상세 매핑 > 원본: `/project/projectMgmtWbsList3.do` (`projectMgmtWbsList3.jsp` 349줄) + 매퍼 `projectMgmtWbsGridList` (project.xml:3854~4280) > 대상: `app/(main)/COMPANY_16/project/progress/page.tsx` + `backend-node/src/services/projectMgmtService.ts` > 작성: 2026-05-11 / 사이클: 구조적 검증 1차 (진행관리 메뉴) ## 1. 운영판 식별 wace_plm 컨트롤러에 진행관리 관련 endpoint 3개 동시 존재: | URL | view | 사용처 | |---|---|---| | `/project/projectMgmtList.do` (L321) | `projectMgmtList.jsp` | 옛 화면 (사용 안 함) | | `/project/projectMgmtList1.do` (L399) | `projectMgmtList1.jsp` | 변종 | | **`/project/projectMgmtWbsList3.do`** (L3243) | **`projectMgmtWbsList3.jsp`** | **RPS 운영판 화면** ✅ | > 운영판 화면 캡처에서 컬럼 라벨(`주문유형/품번/품명/S/N/수주수량/E-BOM/M-BOM/발주일/입고율/제조1,2팀/...`)이 일치하는 jsp를 grep으로 역추적해 확정. ## 2. 항목 매핑 ### 2.1 검색 폼 — wace 활성 11개 (jsp:222-313) | # | wace 라벨 | wace name | RPS filter (`ProgressListFilter`) | 입력 위젯 | 상태 | |---|---|---|---|---|---| | 1 | 년도 | `Year` | `Year` | `` × 2 | ✅ | | 7 | 국내/해외 | `area_cd` | `area_cd` ('국내'/'해외' 라벨) | `` 정적 | ✅ | | 9 | 품번 | `product_item_code` (select2-part) | `search_partObjId` | `PartSelect mode="partNo"` | 🟡 (영업관리 패턴 통일) | | 10 | 품명 | `product_item_name` (select2-part) | `search_partObjId` (공유) | `PartSelect mode="partName"` | 🟡 (영업관리 패턴 통일) | | 11 | S/N | `serial_no` | `serial_no` | `` | ✅ | **비활성** (JSP `<%-- --%>` 블록): `location` / `setup` / `pm_user_id` — 무시. ### 2.2 그리드 컬럼 — wace 8그룹 18셀 → RPS 평탄화 21셀 DataGrid 중첩 헤더 미지원으로 그룹명을 라벨 prefix(이슈/원가/...)로 표현. wace SQL `projectMgmtWbsGridList` 활성 본문 1:1. | # | wace title | wace field | RPS GRID_COLUMNS key | SQL 출처 | 상태 | |---|---|---|---|---|---| | 1 | 프로젝트번호 (frozen) | `PROJECT_NO` | `project_no` | `project_mgmt.project_no` | ✅ | | 2 | 주문유형 | `CATEGORY_NAME` | `category_name` | `CODE_NAME(category_cd)` | ✅ | | 3 | 제품구분 | `PRODUCT_NAME` | `product_name` | `CODE_NAME(product)` | ✅ | | 4 | 국내/해외 | `AREA_NAME` | `area_name` | `CODE_NAME(area_cd)` | ✅ | | 5 | 접수일 | `REG_DATE` | `reg_date` | `TO_CHAR(regdate,'YYYY-MM-DD')` | ✅ | | 6 | 고객사 | `CUSTOMER_NAME` | `customer_name` | `customer_mng` LEFT JOIN | ✅ (RPS 매핑) | | 7 | 유/무상 | `FREE_OF_CHARGE` | `free_of_charge` | `contract_mgmt.paid_type` → '유상'/'무상' | ✅ | | 8 | 품번 | `PRODUCT_ITEM_CODE` | `product_item_code` | `project_mgmt.part_no` | ✅ | | 9 | 품명 | `PRODUCT_ITEM_NAME` | `product_item_name` | `project_mgmt.part_name` | ✅ | | 10 | S/N | `SERIAL_NO` | `serial_no` | `contract_item_serial` 집계 | ✅ | | 11 | 수주수량 | `CONTRACT_QTY` | `contract_qty` | `project_mgmt.quantity::numeric` | ✅ | | 12 | 요청납기 | `REQ_DEL_DATE` | `req_del_date` | COALESCE(`contract_item.due_date`, `project_mgmt.due_date`, `contract_mgmt.due_date`) | ✅ | | 13 | E-BOM | `EBOM_STATUS` | `ebom_status` | `project_mgmt.ebom_status` | ✅ (운영도 대부분 빈값) | | 14 | M-BOM | `MBOM_STATUS` | `mbom_status` | `project_mgmt.mbom_status` | ✅ | | 15 | 발주일 | `ORDER_DATE` | `order_date` | `contract_mgmt.order_date` 스칼라 서브쿼리 | ✅ | | 16 | 입고율 | `RECEIVING_RATE` | `receiving_rate` | `project_mgmt.receiving_rate` | ✅ | | 17 | 제조1,2팀 | `PRODUCTION_TEAM_12` | `production_team_12` | `project_mgmt.production_team_12` | ✅ | | 18 | 제조3팀 | `PRODUCTION_TEAM_3` | `production_team_3` | `project_mgmt.production_team_3` | ✅ | | 19 | 조립 | `ASSEMBLY` | `assembly` | wace SQL에 없음 → NULL | ✅ (운영도 빈값) | | 20 | 검증 | `VERIFICATION` | `verification` | wace SQL에 없음 → NULL | ✅ | | 21 | 출하일 | `SHIPMENT_DATE` | `shipment_date` | `sales_registration.shipping_date` (project_no 매칭, MAX sale_no) | ✅ | ### 2.3 ORDER BY ```sql ORDER BY SUBSTRING(project_no, POSITION('-' IN project_no)+1) DESC, overhaul_order DESC NULLS LAST ``` → "주문유형-제품구분-YYMMDD-NNN" 패턴에서 첫 `-` 이후 부분 내림차순 = 사실상 (제품구분 → YYMMDD → NNN) 역순. ### 2.4 액션 | 동작 | wace | RPS | |---|---|---| | 조회 | `btnSearch` → `/projectMgmtWbsGridList.do` | `GET /api/project/progress/list` | | 프로젝트번호 옵션 | `code_map.project_no = common.getCusProjectNoList` | `GET /api/project/progress/project-no-options` | | **PROJECT_NO 셀 클릭** (cellClick) | `fn_openSaleRegPopup(PROJECT_NO, "detail")` → `/salesMgmt/salesRegForm.do?orderNo={PROJECT_NO}&saleNo=detail` 새 창(read-only 상세 모드) | `ProjectInfoDialog` (같은 탭 다이얼로그) — 그리드 row 객체 그대로 read-only 표시 | 행 클릭은 **PROJECT_NO 컬럼 셀에만** 걸림 (wace `cellClick`). 행 전체 클릭은 그냥 행 선택만. wace의 "detail" 모드 새 창은 RPS에서는 같은 탭 내 `ProjectInfoDialog`로 매핑 — 별도 API 호출 없이 list 응답(`ProgressRow`)을 그대로 다이얼로그에 전달해 read-only 표시. 표시 항목: 프로젝트번호 / 영업번호 / 주문유형 / 제품구분 / 국내해외 / 고객사 / 유무상 / 품번 / 품명 / S/N / 수주수량 / 접수일 / 요청납기 / 발주일 / 프로젝트명 / 작성자. ## 3. RPS 매핑 변경 사항 | wace 분기 | RPS 매핑 | 이유 | |---|---|---| | `CASE WHEN customer_objid LIKE 'C_%' THEN client_mng ELSE supply_mng END` | `LEFT JOIN customer_mng ON customer_code = substring/통합` | RPS는 `customer_mng` 단일 마스터 (영업관리 G1 자산) | | `product_item_code` / `product_item_name` LIKE 텍스트 검색 | `search_partObjId` 단일 part_objid 매칭 | 영업관리 패턴 통일 + RPS의 PartSelect 컴포넌트 재사용 | | `CODE_NAME(...)` 함수 호출 | 동일 (RPS DB 함수 보유) | 영업관리는 LEFT JOIN 패턴이지만 진행관리는 함수 호출 12회로 가독성 우선 | ## 4. 의존 테이블 (활성 SQL 기준 20개 중 RPS 보유 12개) ✅ `project_mgmt`(메인) / `contract_mgmt` / `contract_item` / `contract_item_serial` / `customer_mng` / `user_info` / `comm_code` + `CODE_NAME()` 함수 / `attach_file_info` / `sales_registration` / `part_mng` ❌ `pms_wbs_task` / `setup_wbs_task` / `assembly_wbs_task` / `bom_part_qty` / `part_bom_report` / `planning_issue` / `release_mgmt` / `input_cost_goal` / `expense_master/detail` / `work_diary` → 부재한 테이블이 의존하는 SQL 항목들(진척율 / 이슈 카운트 / 투입원가 / 출고)은 wace JSP 그리드 컬럼 정의에 **노출되지 않음** (8그룹 18셀에 포함 X). 따라서 그리드 표시 데이터엔 영향 없음. backend SQL은 `0` / `NULL` 자리만 유지 후 P2(WBS) 이식에서 채움. ## 5. 미구현 / P1.5+ 보류 | 항목 | 메모 | |---|---| | 다중 프로젝트번호 선택 | wace는 multi-select2. RPS는 단일(`SmartSelect`). 다중 모드는 P1.5에서 보강 가능 | | 진척율 / 이슈 / 원가 / 출고 컬럼 채움 | 그리드 표시 컬럼엔 없으므로 영향 없음. 그러나 service SQL의 `0` 자리들은 P2에서 활성화 | | `getById` / `updateProject` 라우트 | 옛 jsp(projectMgmtList) 기반 자리. 행 클릭이 `ProjectInfoDialog` (list row 직접 사용)로 통일됐으므로 미사용 — 삭제 검토 가능 | | 엑셀 다운로드 | wace에 없음 — 본 PR 제외 | ## 6. 관련 파일 - backend: [services/projectMgmtService.ts](../../backend-node/src/services/projectMgmtService.ts) · [controllers/projectMgmtController.ts](../../backend-node/src/controllers/projectMgmtController.ts) · [routes/projectMgmtRoutes.ts](../../backend-node/src/routes/projectMgmtRoutes.ts) - frontend: [app/(main)/COMPANY_16/project/progress/page.tsx](../../frontend/app/(main)/COMPANY_16/project/progress/page.tsx) · [components/project/ProjectInfoDialog.tsx](../../frontend/components/project/ProjectInfoDialog.tsx) · [lib/api/projectMgmt.ts](../../frontend/lib/api/projectMgmt.ts) - 검증: [01-progress-verify.md](./01-progress-verify.md)