ABAP

EWM 창고 오더 실수 3가지 #shorts #SAP #ABAP

▶ YouTube에서 보기

개요 및 이 글에서 다루는 범위

SAP S/4HANA EWM(Extended Warehouse Management) 환경에서 창고 운영의 중심에는 WarehouseOrder가 있습니다. 이 글은 I_WarehouseOrder CDS View의 구조를 해부하고, 이를 통해 창고 오더와 하위 태스크(WarehouseTask)가 어떻게 묶이고 처리되는지를 ABAP/CDS 관점에서 풀어냅니다. 실무에서 자주 마주치는 컨솔리데이션(consolidation) 그룹, 처리 상태 추적, 그리고 분석용 어소시에이션 활용까지 단계적으로 다룹니다.

  • I_WarehouseOrder의 핵심 필드와 키 구조 이해
  • 창고 오더(WO)와 창고 태스크(WT)의 1:N 관계 파악
  • 컨솔리데이션 그룹과 처리 상태 코드의 의미 해석
  • CDS 어소시에이션을 활용한 실전 조회 패턴 작성
  • 운영 단계에서 발생할 수 있는 성능·권한 이슈 대응

읽기 전 알아두면 좋은 것

이 글은 ABAP CDS View 정의 문법(define view entity, association, composition)에 대한 기본 이해와, EWM의 도큐먼트 흐름(Inbound/Outbound Delivery → Warehouse Request → Warehouse Task → Warehouse Order)에 대한 개략적인 지식을 전제로 합니다. ABAP RAP(RESTful ABAP Programming Model)이나 Fiori Elements 화면 개발 경험이 있다면 후반 어소시에이션 활용 예제를 더 빠르게 이해할 수 있습니다.

환경 및 사전 준비

예제는 다음 환경을 기준으로 합니다. 릴리스에 따라 필드명이나 어소시에이션 이름이 미세하게 다를 수 있으므로, 실제 시스템의 ADT(ABAP Development Tools)에서 View를 직접 열어 확인하는 것을 권장합니다.

  • SAP S/4HANA 2022 / 2023 (On-Premise 또는 Private Cloud Edition)
  • Embedded EWM 또는 Decentralized EWM 활성화 상태
  • ABAP Development Tools(Eclipse 기반 ADT) 최신 버전
  • 권한 오브젝트: S_TABU_DIS(테이블 조회), /SCWM/WO(창고 오더 권한)
  • 샘플 데이터: 최소 하나 이상의 창고 번호(Warehouse Number)와 활성화된 창고 오더

SAP Cloud ABAP Environment(BTP ABAP Environment)에서는 EWM 관련 CDS View 일부가 Released API로 노출되지 않을 수 있으므로, On-Premise 또는 Private Cloud 환경을 일반적으로 권장합니다.

핵심 개념: 창고 오더는 "작업 묶음 봉투"다

EWM에서 창고 오더(Warehouse Order)를 가장 쉽게 비유하면 "현장 작업자에게 전달되는 작업 묶음 봉투"입니다. 봉투 안에는 여러 장의 작업 지시서(Warehouse Task)가 들어있고, 작업자는 이 봉투 단위로 RF 단말기에서 작업을 받습니다. 즉, Warehouse Task는 "무엇을 어디서 어디로 옮길지"를 정의하고, Warehouse Order는 "이 작업들을 누가 묶음으로 처리할지"를 정의합니다.

Warehouse Request(요청) → Warehouse Task(개별 이동 지시) → Warehouse Order(작업자 단위 묶음) → 실행/확정

I_WarehouseOrder는 이 "봉투" 자체의 헤더 정보를 표현하는 Basic View(Interface View)입니다. 표준 명명 규칙상 I_ 접두사는 재사용 가능한 인터페이스 레이어를 의미하며, 그 위에 C_(Consumption) 뷰가 올라가 Fiori 앱이나 분석 리포트에 사용됩니다.

핵심 필드를 도식화하면 다음과 같습니다.

  • EWMWarehouse: 창고 번호 (예: 1710) — 키 필드
  • WarehouseOrder: 창고 오더 번호 (10자리) — 키 필드
  • WarehouseOrderType: 오더 유형(피킹/푸팅/리플레니시 등)
  • WarehouseProcessType: 프로세스 유형(이동 종류 분류)
  • ActivityArea: 활동 영역(작업자가 담당하는 구역)
  • ConsolidationGroup: 컨솔리데이션 그룹(피킹 후 합쳐질 단위)
  • WarehouseOrderStatus: 상태 코드(미시작/진행중/완료 등)
  • WarehouseOrderCreationDateTime: 생성 일시
  • WarehouseOrderExecutingUser: 실행 담당 사용자

여기서 ConsolidationGroup은 특히 중요한데, 동일한 출고처(예: 같은 출고 도크, 같은 적재 차량)로 가는 피킹 태스크들을 묶어 후속 패킹/적재 단계의 효율을 높이는 키 역할을 합니다.

1단계: 기본 조회 예제

가장 먼저 특정 창고의 활성 창고 오더 목록을 가져오는 단순 조회 예제를 작성해봅니다. 시나리오는 "1710 창고에서 오늘 생성된 미완료 오더 조회"입니다.

REPORT z_demo_warehouse_order_list.

DATA: lt_orders TYPE STANDARD TABLE OF i_warehouseorder,
      ls_order  TYPE i_warehouseorder.

SELECT ewmwarehouse,
       warehouseorder,
       warehouseordertype,
       activityarea,
       consolidationgroup,
       warehouseorderstatus,
       warehouseordercreationdatetime
  FROM i_warehouseorder
  WHERE ewmwarehouse = '1710'
    AND warehouseorderstatus <> 'C'
    AND warehouseordercreationdatetime >= @( cl_abap_context_info=>get_system_date( ) )
  INTO TABLE @lt_orders.

LOOP AT lt_orders INTO ls_order.
  WRITE: / ls_order-warehouseorder,
           ls_order-activityarea,
           ls_order-consolidationgroup,
           ls_order-warehouseorderstatus.
ENDLOOP.

이 코드는 I_WarehouseOrder를 직접 SELECT 하는 가장 기본 형태입니다. 상태 코드는 시스템마다 커스터마이징될 수 있으므로, 도메인 값(/SCWM/DE_WO_STATUS 계열)을 ADT의 Data Preview로 먼저 확인하는 것을 권장합니다.

2단계: 어소시에이션으로 태스크까지 묶어 조회

실무에서는 "이 오더에 어떤 태스크가 묶여 있는가"를 함께 봐야 합니다. I_WarehouseOrderI_WarehouseTask와의 어소시에이션을 제공합니다(릴리스에 따라 _WarehouseTask 또는 _Task). 출고 피킹 시나리오를 가정해 컨솔리데이션 그룹별 태스크 수량을 집계하는 커스텀 CDS View를 만들어봅니다.

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Picking Order Consolidation Overview'
define view entity ZC_PickingOrderConsolidation
  as select from I_WarehouseOrder as WhOrder
  association [0..*] to I_WarehouseTask as _Task
    on  $projection.EWMWarehouse   = _Task.EWMWarehouse
    and $projection.WarehouseOrder = _Task.WarehouseOrder
{
  key WhOrder.EWMWarehouse,
  key WhOrder.WarehouseOrder,
      WhOrder.WarehouseOrderType,
      WhOrder.ActivityArea,
      WhOrder.ConsolidationGroup,
      WhOrder.WarehouseOrderStatus,
      WhOrder.WarehouseOrderExecutingUser,
      WhOrder.WarehouseOrderCreationDateTime,

      cast(
        ( select count(*) from I_WarehouseTask as T
            where T.EWMWarehouse   = WhOrder.EWMWarehouse
              and T.WarehouseOrder = WhOrder.WarehouseOrder )
        as abap.int4
      )                                                  as TaskCount,

      _Task
}

이렇게 정의해두면 ABAP 코드에서 path expression으로 헤더-아이템을 한 번에 조회할 수 있습니다.

DATA: lt_overview TYPE TABLE OF zc_pickingorderconsolidation.

TRY.
    SELECT FROM zc_pickingorderconsolidation
           FIELDS ewmwarehouse,
                  warehouseorder,
                  consolidationgroup,
                  taskcount,
                  warehouseorderstatus
           WHERE  ewmwarehouse = '1710'
             AND  consolidationgroup IS NOT INITIAL
           ORDER BY consolidationgroup
           INTO TABLE @lt_overview.

    cl_demo_output=>display( lt_overview ).

  CATCH cx_sy_open_sql_db INTO DATA(lx_sql).
    MESSAGE lx_sql->get_text( ) TYPE 'E'.
ENDTRY.

여기서 주목할 점은 두 가지입니다. 첫째, WarehouseOrder 키는 항상 EWMWarehouse와 함께 묶여야 합니다(창고 간 번호가 중복 가능). 둘째, 서브쿼리로 카운트를 가져오는 방식보다는 가능하면 $projection과 어소시에이션을 활용해 HANA 옵티마이저가 푸시다운할 수 있게 작성하는 편이 일반적으로 권장됩니다.

3단계: 운영급 활용 — 상태 모니터링 클래스

마지막 단계에서는 위 View를 감싸 재사용 가능한 ABAP 클래스로 캡슐화합니다. 권한 체크, 로깅, 단위 테스트 가능성을 함께 고려합니다.

CLASS zcl_wo_consolidation_monitor DEFINITION
  PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.
    TYPES: BEGIN OF ty_summary,
             consolidation_group TYPE c LENGTH 10,
             open_orders         TYPE i,
             total_tasks         TYPE i,
           END OF ty_summary,
           tt_summary TYPE STANDARD TABLE OF ty_summary WITH EMPTY KEY.

    METHODS get_open_summary
      IMPORTING iv_warehouse     TYPE /scwm/lgnum
      RETURNING VALUE(rt_result) TYPE tt_summary
      RAISING   cx_sy_open_sql_db.

  PRIVATE SECTION.
    CONSTANTS c_status_completed TYPE c LENGTH 1 VALUE 'C'.
ENDCLASS.

CLASS zcl_wo_consolidation_monitor IMPLEMENTATION.
  METHOD get_open_summary.

    AUTHORITY-CHECK OBJECT '/SCWM/WO'
             ID '/SCWM/LGN' FIELD iv_warehouse
             ID 'ACTVT'     FIELD '03'.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE cx_sy_open_sql_db
        EXPORTING textid = cx_sy_open_sql_db=>cx_sy_open_sql_db.
    ENDIF.

    SELECT consolidationgroup,
           COUNT( * )            AS open_orders,
           SUM( taskcount )      AS total_tasks
      FROM zc_pickingorderconsolidation
      WHERE ewmwarehouse        = @iv_warehouse
        AND warehouseorderstatus <> @c_status_completed
        AND consolidationgroup  IS NOT INITIAL
      GROUP BY consolidationgroup
      ORDER BY consolidationgroup
      INTO CORRESPONDING FIELDS OF TABLE @rt_result.

  ENDMETHOD.
ENDCLASS.

운영 환경에서는 다음을 추가로 고려합니다.

  • 인덱스 활용: EWMWarehouse + WarehouseOrderStatus 조건은 자주 사용되므로, 인덱스 푸시다운이 가능한 SQL 형태로 유지
  • 대용량 페이징: 하루 수십만 건 처리되는 창고에서는 UP TO n ROWS 또는 OFFSET 페이징 필수
  • 단위 테스트: cl_cds_test_environment로 테스트 더블 환경을 구성, 실제 EWM 데이터 없이도 로직 검증

현장에서 자주 막히는 지점들

Q1. I_WarehouseOrder를 찾았는데 데이터가 비어있어요.
임베디드 EWM이 활성화되어 있는지, 그리고 해당 사용자가 창고 번호에 대한 권한(/SCWM/LGN)을 가지고 있는지 먼저 확인합니다. Released API 여부는 ADT의 "API State"에서 확인할 수 있으며, Use-System-Internally 상태인 경우 커스텀 코드에서 직접 참조가 제한될 수 있습니다.

Q2. WarehouseOrder와 WarehouseTask가 1:1처럼 보입니다.
시스템 커스터마이징(Warehouse Order Creation Rule)에 따라 태스크가 자동으로 묶이는 정도가 달라집니다. 단일 태스크만 묶이는 룰이 설정되어 있다면 외관상 1:1로 보이지만, 데이터 모델 자체는 항상 1:N입니다. 룰은 IMG의 Cross-Process Settings → Warehouse Order → Define Creation Rule에서 확인합니다.

Q3. ConsolidationGroup이 항상 비어있어요.
컨솔리데이션 그룹은 주로 출고 프로세스(피킹 후 패킹/스테이징이 필요한 경우)에서 채워집니다. 입고 푸팅 오더에서는 비어 있는 것이 정상입니다. 또한 컨솔리데이션 그룹 결정 규칙(Determination)이 설정되어 있어야 자동 부여됩니다.

Q4. 성능이 느립니다.
SELECT *를 피하고 필요한 필드만 명시, WarehouseOrderCreationDateTime 같은 날짜 범위 조건을 반드시 포함, 그리고 어소시에이션을 통한 path expression이 서브쿼리보다 일반적으로 더 잘 푸시다운됩니다.

이어서 살펴볼 만한 주제

이 글에서 다룬 I_WarehouseOrder는 EWM 데이터 모델의 시작점일 뿐입니다. 한 걸음 더 나아가려면 다음 영역으로 학습을 확장하는 것을 권장합니다.

  • I_WarehouseTaskI_WarehouseRequest의 헤더-아이템 구조 비교
  • RAP(Behavior Definition)로 창고 오더 상태 변경 액션 모델링
  • Wave Management(I_Wave)와 창고 오더 묶음의 상위 개념 연결
  • Embedded Analytics CDS Cube를 활용한 창고 KPI 대시보드 구성
  • SAP Build Process Automation으로 미완료 오더 알림 자동화

참고할 만한 외부 자료

  • SAP Help Portal — SAP S/4HANA On-Premise Documentation
  • SAP Help Portal — Extended Warehouse Management
  • SAP Help Portal — ABAP CDS Views
  • SAP Community — Extended Warehouse Management
  • SAP Business Accelerator Hub — EWM Released APIs

댓글 0

아직 댓글이 없습니다.