Files
vexplor/docs/shipping-plan-editor-plan.md
kjs 9decf13068 feat: implement shipping plan management features
- Added shipping plan routes and controller to handle aggregate and batch save operations.
- Introduced a new shipping plan editor component for bulk registration of shipping plans based on selected orders.
- Enhanced API client functions for fetching aggregated shipping plan data and saving plans in bulk.
- Updated the registry to include the new shipping plan editor component, improving the overall shipping management workflow.

These changes aim to streamline the shipping plan process, allowing for efficient management and registration of shipping plans in the application.
2026-03-18 14:42:47 +09:00

6.0 KiB

출하계획 동시 등록 컴포넌트 (v2-shipping-plan-editor) 설계서

개요

수주 목록에서 다건 선택 후 "출하계획" 버튼 클릭 시 모달로 열리는 출하계획 일괄 등록 화면. 기존 ScreenModal + modalScreenId 매커니즘을 활용하여, DB 기반 화면(screen_definitions)으로 구현한다.

핵심 기능

  1. 선택된 수주를 품목(part_code) 기준으로 그룹핑
  2. 그룹별 5칸 집계 카드: 총수주잔량, 총 출하계획량, 현재고, 가용재고, 생산중수량
  3. 그룹별 상세 테이블: 기존 계획(기존) + 신규 입력(신규) 구분 표시
  4. 출하계획량만 입력 → 확인 시 shipment_plan에 일괄 INSERT

테이블 관계

sales_order_mng (수주)
  ├─ id (PK)
  ├─ part_code (품목코드) ← 그룹핑 기준
  ├─ part_name (품명)
  ├─ order_qty (수주수량)
  ├─ ship_qty (출하수량)
  ├─ balance_qty (잔량) = order_qty - ship_qty
  ├─ partner_id (거래처)
  └─ due_date (납기일)

shipment_plan (출하계획)
  ├─ sales_order_id (FK → sales_order_mng.id)
  ├─ plan_qty (출하계획수량)
  ├─ plan_date (출하예정일)
  ├─ shipment_plan_no (자동 채번)
  └─ status (READY)

inventory_stock (재고)
  ├─ item_code (품목코드)
  └─ current_qty (현재고)

production_plan_mng (생산계획)
  ├─ item_code (품목코드)
  ├─ plan_qty (계획수량)
  ├─ completed_qty (완료수량)
  └─ status (진행중 = in_progress / planned)

집계 카드 데이터 소스

카드 계산 방법
총수주잔량 SUM(sales_order_mng.balance_qty) WHERE part_code = ?
총 출하계획량 SUM(shipment_plan.plan_qty) WHERE sales_order_id IN (해당 품목 수주들)
현재고 SUM(inventory_stock.current_qty) WHERE item_code = part_code
가용재고 현재고 - 총 출하계획량 (기존 계획분)
생산중수량 SUM(production_plan_mng.plan_qty - completed_qty) WHERE item_code = part_code AND status IN ('in_progress', 'planned')

상세 테이블 컬럼

컬럼 소스 편집
구분 "기존" or "신규" 읽기 전용 (배지)
수주번호 sales_order_mng.order_no 읽기 전용
거래처 sales_order_mng.partner_id (엔티티 조인) 읽기 전용
납기일 sales_order_mng.due_date 읽기 전용
미출하 sales_order_mng.balance_qty 읽기 전용
출하계획량 입력값 / shipment_plan.plan_qty 입력 가능

데이터 흐름

1. 수주 목록에서 체크박스 선택 → "출하계획" 버튼 클릭
2. openScreenModal 이벤트 발생 (selectedData = 선택된 수주 배열)
3. ScreenModal이 모달 화면 로드 (v2-shipping-plan-editor 컴포넌트)
4. 컴포넌트가 groupedData (= selectedData) 수신
5. part_code 기준 그룹핑
6. 백엔드 API 호출: GET /api/shipping-plan/aggregate
   → 품목별 재고, 생산중수량, 기존 출하계획 조회
7. UI 렌더링 (집계 카드 + 상세 테이블)
8. 사용자가 출하계획량 입력
9. 확인 버튼 → POST /api/shipping-plan/batch
   → shipment_plan INSERT + sales_order_mng.plan_ship_qty UPDATE

파일 구조

frontend/lib/registry/components/v2-shipping-plan-editor/
  ├── index.ts                              # createComponentDefinition
  ├── ShippingPlanEditorRenderer.tsx         # AutoRegisteringComponentRenderer
  ├── ShippingPlanEditorComponent.tsx        # 메인 UI 컴포넌트
  └── types.ts                              # 타입 정의

frontend/lib/api/
  └── shipping.ts                           # API 클라이언트 함수

backend-node/src/
  ├── controllers/shippingPlanController.ts  # API 핸들러
  └── routes/shippingPlanRoutes.ts          # 라우터

백엔드 API

GET /api/shipping-plan/aggregate

품목별 집계 + 기존 출하계획 조회

Request: ?partCodes=ITEM001,SEAL-100&orderIds=172,175,178 Response:

{
  "success": true,
  "data": {
    "ITEM001": {
      "totalBalance": 1700,
      "totalPlanQty": 500,
      "currentStock": 1000,
      "availableStock": 500,
      "inProductionQty": 300,
      "existingPlans": [
        { "id": 76, "salesOrderId": 172, "planQty": 500, "planDate": "2025-12-10", "shipmentPlanNo": "SPL-..." }
      ]
    }
  }
}

POST /api/shipping-plan/batch

출하계획 일괄 저장

Request:

{
  "plans": [
    { "salesOrderId": 172, "planQty": 1000 },
    { "salesOrderId": 175, "planQty": 500 }
  ]
}

구현 상태

완료

  • types.ts (타입 정의)
  • index.ts (컴포넌트 정의)
  • ShippingPlanEditorRenderer.tsx (레지스트리 등록)
  • ShippingPlanEditorComponent.tsx (메인 UI)
  • frontend/lib/api/shipping.ts (API 클라이언트)
  • backend-node/src/controllers/shippingPlanController.ts (집계 + 일괄 저장)
  • backend-node/src/routes/shippingPlanRoutes.ts (라우터)
  • screen_definitions (screen_id: 4573, screen_code: *_SHIP_PLAN_EDITOR)
  • screen_layouts_v2 (layout_id: 11562)

연동 정보

항목 마스터(*) 탑씰(COMPANY_7)
screen_id 4573 4574
screen_code *_SHIP_PLAN_EDITOR TOPSEAL_SHIP_PLAN_EDITOR
layout_id 11562 11563

탑씰 수주관리 화면(screen_id: 156)의 "출하계획" 버튼(comp_33659)이 targetScreenId: 4574로 연결되어, 체크박스 선택 → 버튼 클릭 → 모달 오픈. 선택된 수주 데이터는 groupedData prop으로 전달됨.

테스트 계획

1단계: 기본 기능

  • 수주 선택 → 모달 열기 → groupedData 수신 확인
  • part_code 기준 그룹핑 확인
  • 집계 카드 데이터 표시 확인

2단계: CRUD

  • 출하계획량 입력 → 집계 자동 재계산
  • 확인 버튼 → shipment_plan INSERT 확인
  • 기존 계획 "기존" 배지 표시 확인

3단계: 검증

  • 출하계획량 > 미출하 시 에러 처리
  • 멀티테넌시 (company_code) 필터링 확인