개요 및 이 글에서 다루는 범위
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_WarehouseOrder는 I_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_WarehouseTask와I_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
아직 댓글이 없습니다.