개요와 이 글에서 다루는 범위
SAP S/4HANA의 Extended Warehouse Management(EWM) 환경에서 저장 빈(Storage Bin)은 물리적 보관 위치를 식별하는 최소 단위입니다. I_StorageBin은 LGPLA 테이블 계열을 기반으로 만들어진 CDS 기본 뷰(Basic View)로, 빈 마스터 데이터를 OData/RAP/CDS 쿼리 환경에서 일관되게 조회할 수 있게 해주는 핵심 자산입니다. 이 글에서는 I_StorageBin의 데이터 모델과 동작 원리, 실전 활용법을 단계적으로 살펴봅니다.
- LGPLA 테이블 구조와
I_StorageBin의 매핑 관계 이해 - 창고(Warehouse Number) - 저장 타입(Storage Type) - 빈(Bin) 계층 파악
- Association을 활용한 마스터/트랜잭션 데이터 조합 조회
- RAP/UI5 시나리오에서 빈 마스터를 소비하는 패턴
- 성능 최적화 및 권한(Authorization) 적용 포인트
먼저 알고 있어야 할 것
이 글은 ABAP CDS의 기본 문법(define view, association, annotation)과 EWM의 기본 개념(창고 번호, 저장 타입, 빈 섹션)에 어느 정도 익숙한 독자를 가정합니다. 추가로 ADT(ABAP Development Tools), Eclipse 환경에서 CDS 뷰를 검색·미리보기할 수 있는 정도의 경험이 있으면 실습이 매끄럽게 진행됩니다. RAP(RESTful Application Programming Model)에 대한 기초 지식도 3단계 예제 이해에 도움이 됩니다.
환경과 버전, 준비 항목
이 글의 예제는 다음 환경을 기준으로 작성되었습니다.
- SAP S/4HANA 2022 또는 2023 (On-Premise / Private Cloud Edition)
- Decentralized EWM 또는 Embedded EWM 활성화
- ABAP Development Tools(ADT) for Eclipse 2024-06 이상
- 권한:
S_RS_AUTH, EWM 창고 권한(/SCWM/MFL등) 일반적으로 권장 - 테스트 데이터:
/SCWM/RFUI또는 EWM Easy Graphics를 통해 사전 생성된 빈 마스터
SAP BTP ABAP Environment(Steampunk)에서도 동일한 이름의 뷰가 릴리스 상태(C1/C2)에 따라 노출될 수 있으나, 본 글의 일부 association은 On-Premise 기준입니다. 사용 전 ADT의 "Where-Used"와 Release Contract를 확인하는 것을 일반적으로 권장합니다.
핵심 개념: LGPLA와 I_StorageBin의 관계
EWM에서 저장 빈은 /SCWM/LAGP(EWM Storage Bin) 테이블로 관리되지만, 전통적인 WM(Warehouse Management) 모듈에서는 LAGP와 함께 빈 좌표 정보가 LGPLA(Storage Bins)에 저장됩니다. I_StorageBin은 이러한 빈 마스터를 의미 있는 비즈니스 엔티티로 추상화하여 노출하는 CDS 기본 뷰입니다.
창고(Warehouse Number) → 저장 타입(Storage Type) → 저장 섹션(Storage Section) → 저장 빈(Storage Bin)으로 이어지는 4단계 계층이 있다고 생각하면 이해가 쉽습니다. 도서관에 비유하면, 창고는 "건물", 저장 타입은 "층", 섹션은 "서가 줄", 빈은 "정확한 책꽂이 칸"에 해당합니다.
이 뷰의 일반적인 주요 필드 구성은 다음과 같습니다.
WarehouseNumber(LGNUM) — 창고 번호, 4자리 키StorageBin(LGPLA) — 빈 식별자, 보통 10~18자리StorageType(LGTYP) — 저장 타입StorageSection(LGBER) — 섹션StorageBinAccessType,StorageBinType— 접근/빈 유형- 좌표(X, Y, Z 또는 통로/스택/레벨), 최대 적재량 등 물리 속성
I_StorageBin은 일반적으로 Composition이나 Association을 통해 I_Warehouse, I_StorageType, I_Product 등과 연결되어, 빈에 보관된 자재나 창고 마스터 정보를 한 번에 조회할 수 있게 설계됩니다. 또한 @ObjectModel.representativeKey로 StorageBin 필드가 지정되어 UI 환경에서 자동으로 Value Help가 동작합니다.
실전 예제 1단계: 기본 조회
가장 먼저 ADT의 Data Preview로 I_StorageBin의 구조를 확인해 봅니다. 그리고 자체 컨슈머 뷰를 만들어 필요한 필드만 추려내는 패턴을 익혀봅니다.
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Cold Chain Warehouse Bin Overview'
define view entity ZC_ColdChainBin
as select from I_StorageBin as Bin
{
key Bin.WarehouseNumber as WarehouseId,
key Bin.StorageBin as BinCode,
Bin.StorageType as StorageTypeCode,
Bin.StorageSection as SectionCode,
Bin.StorageBinType as BinPhysicalType,
Bin.MaximumWeight as MaxWeight,
Bin.WeightUnit as WeightUom,
Bin.AisleInWarehouse as Aisle,
Bin.StackInWarehouse as Stack,
Bin.LevelInWarehouse as VerticalLevel
}
where Bin.WarehouseNumber = 'CL01'
and Bin.StorageType in ('R01', 'R02');
이 예제는 콜드체인 창고(CL01)의 냉장 저장 타입(R01, R02) 빈만 조회합니다. ADT에서 F8(Data Preview)로 결과를 즉시 확인할 수 있고, 필요한 경우 OData V2/V4 서비스로 노출해 Fiori Elements List Report로 바로 활용할 수 있습니다.
실전 예제 2단계: 재고와 조합한 실무 시나리오
실제 물류 운영에서는 "비어있는 빈" 또는 "특정 자재가 보관된 빈"을 빠르게 식별해야 하는 요건이 빈번합니다. 이 단계에서는 I_StorageBin을 재고 뷰와 결합하고, 결과가 비어 있을 때의 로깅 처리까지 다룹니다.
@EndUserText.label: 'Bin Occupancy with Stock Join'
define view entity ZC_BinOccupancy
as select from I_StorageBin as Bin
left outer join I_PhysicalStockByStorageBin as Stk
on Bin.WarehouseNumber = Stk.WarehouseNumber
and Bin.StorageBin = Stk.StorageBin
association [0..1] to I_StorageType as _StorageType
on $projection.WarehouseId = _StorageType.WarehouseNumber
and $projection.StorageTypeCode = _StorageType.StorageType
{
key Bin.WarehouseNumber as WarehouseId,
key Bin.StorageBin as BinCode,
Bin.StorageType as StorageTypeCode,
case when Stk.Product is initial
then 'EMPTY'
else 'OCCUPIED'
end as OccupancyStatus,
Stk.Product as ProductCode,
Stk.Quantity as OnHandQuantity,
Stk.QuantityUnit as Uom,
_StorageType
}
이 뷰를 호출하는 ABAP 클래스에서는 결과 검증과 Application Log를 함께 작성하는 것이 운영 측면에서 유리합니다.
METHOD fetch_empty_bins.
DATA(lo_log) = cl_bali_log_db_writer=>create_instance( ).
SELECT FROM zc_binoccupancy
FIELDS warehouseid, bincode, storagetypecode
WHERE warehouseid = @iv_warehouse
AND occupancystatus = 'EMPTY'
INTO TABLE @DATA(lt_empty).
IF lt_empty IS INITIAL.
MESSAGE i208(00) WITH 'No empty bins found in' iv_warehouse INTO DATA(lv_msg).
lo_log->add_message( cl_bali_message_setter=>create( severity = if_bali_constants=>c_severity_warning
text = lv_msg ) ).
RETURN.
ENDIF.
rt_empty_bins = lt_empty.
ENDMETHOD.
실전 예제 3단계: 프로덕션 수준 RAP 노출
마지막 단계로 RAP의 read-only 모델로 I_StorageBin을 컨슈밍해 OData V4 서비스로 노출하고, 권한·성능·테스트 포인트를 함께 다룹니다.
@AccessControl.authorizationCheck: #CHECK
@Metadata.allowExtensions: true
@Search.searchable: true
define root view entity ZR_BinMaster
as select from I_StorageBin as Bin
association [0..*] to I_PhysicalStockByStorageBin as _Stock
on $projection.WarehouseId = _Stock.WarehouseNumber
and $projection.BinCode = _Stock.StorageBin
{
@Search.defaultSearchElement: true
key Bin.WarehouseNumber as WarehouseId,
@Search.defaultSearchElement: true
key Bin.StorageBin as BinCode,
Bin.StorageType as StorageTypeCode,
Bin.MaximumWeight as MaxWeight,
Bin.WeightUnit as WeightUom,
_Stock
}
CLASS zcl_bin_service_perf DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS read_bins_paged
IMPORTING iv_warehouse TYPE /scwm/lgnum
iv_top TYPE i DEFAULT 500
iv_skip TYPE i DEFAULT 0
RETURNING VALUE(rt_bins) TYPE STANDARD TABLE OF zr_binmaster WITH EMPTY KEY.
ENDCLASS.
CLASS zcl_bin_service_perf IMPLEMENTATION.
METHOD read_bins_paged.
SELECT FROM zr_binmaster
FIELDS warehouseid, bincode, storagetypecode, maxweight, weightuom
WHERE warehouseid = @iv_warehouse
ORDER BY bincode
INTO TABLE @rt_bins
OFFSET @iv_skip
UP TO @iv_top ROWS.
ENDMETHOD.
ENDCLASS.
운영 환경에서 고려할 점은 다음과 같습니다.
- 권한:
@AccessControl.authorizationCheck: #CHECK와 DCL(Data Control Language)로 창고 단위 접근 제한을 적용 - 성능: 빈은 수십만 건이 될 수 있으므로 항상
WarehouseNumber + StorageType조건 또는 페이징 사용을 일반적으로 권장 - 테스트: ABAP Unit으로
cl_cds_test_environment를 활용해 LGPLA 테스트 데이터를 격리 주입 - 모니터링: SQL Monitor(
SQLM)와 CDS View Statistics로 자주 호출되는 필터 패턴 식별
자주 부딪히는 함정과 해결법
Q1. I_StorageBin이 ADT에서 검색되지 않습니다.
시스템에 EWM 컴포넌트가 활성화되어 있지 않거나, S/4HANA 릴리스에 따라 뷰명이 다를 수 있습니다. I_EWMStorageBin 또는 I_WhseStorageBin 형태로 존재하는 경우가 있으니 ADT의 "Open CDS Entity" 다이얼로그에서 와일드카드(*StorageBin*)로 확인해 보세요.
Q2. Data Preview 결과가 비어 있습니다.
EWM 빈 마스터(/SCWM/LS01)는 클라이언트별로 데이터가 분리됩니다. 또한 DCL에 의해 본인이 권한을 가진 창고만 노출되므로, SU53으로 권한 부재 여부를 점검하고, 테스트 시 WITH PRIVILEGED ACCESS 옵션은 운영 코드에서 사용하지 않는 것을 일반적으로 권장합니다.
Q3. Join 후 빈 행이 중복으로 늘어납니다.
재고 뷰(I_PhysicalStockByStorageBin 등)와 left join 시, 동일 빈에 여러 자재가 있으면 카디널리티가 증가합니다. 빈 수준 집계가 목표라면 group by와 sum()을 명시하거나, association을 통한 lazy join으로 전환하면 성능과 결과 정합성이 모두 개선됩니다.
이어서 살펴보면 좋은 주제
이 글의 내용을 마쳤다면, 다음 주제로 확장하면 EWM 데이터 모델을 더 입체적으로 이해할 수 있습니다.
I_HandlingUnit과I_PhysicalStockByStorageBin을 결합한 HU 단위 재고 분석- RAP Behavior Definition으로 빈 마스터에 메모(notes) 필드를 사용자 확장(
extend)하는 방법 - Embedded Analytics:
I_StorageBin기반 Analytical Query로 가동률 KPI 작성 - SAP Build Apps 또는 Fiori Elements로 빈 검색 화면 구성
- CDS View Entity vs. 기존 DDIC View의 마이그레이션 전략
더 읽어볼 자료
- SAP S/4HANA Product Documentation (help.sap.com)
- SAP Extended Warehouse Management - Storage Bin Concepts (help.sap.com)
- ABAP CDS - Core Data Services Reference (help.sap.com)
- RAP Developer Guide - Read-Only Service (help.sap.com)
- SAP Community - ABAP CDS & EWM Tag
- SAP Blogs - Warehouse Management Insights
댓글 0
아직 댓글이 없습니다.