ABAP

EKET 직접 조회 그만 — CDS 납기 뷰로 바꾸기 #shorts #SAP #ABAP

1. EKET 테이블이란 무엇인가 — 구매 납기일정의 원본

SAP ERP/S/4HANA의 구매 모듈에서 가장 빈번하게 조회되는 테이블 중 하나가 바로 EKET입니다. EKET는 "Einkaufsbelegterminierung"의 약어로, 풀어쓰면 Purchasing Document: Delivery Schedule입니다. 즉 구매 오더(Purchase Order, EKKO/EKPO) 한 라인 아이템에 대해 언제, 얼마만큼 납품받기로 했는지를 나타내는 "납기 스케줄 라인"을 저장합니다.

구매 오더 한 건은 보통 다음 구조로 펼쳐집니다.

  • EKKO: 헤더 (벤더, 회사코드, 결제조건)
  • EKPO: 아이템 라인 (자재, 수량, 단가, 플랜트)
  • EKET: 납기 스케줄 라인 (납기일자, 분할 수량, 인도된 수량)

예를 들어 자재 100개를 한 PO 아이템으로 발주했더라도, 실제로는 "1월 30개, 2월 50개, 3월 20개"로 나누어 받기로 했다면 EKET에는 3개의 레코드가 만들어집니다. 이 분할 단위가 바로 Schedule Line이며, MRP·재고 가용성·납기 지연 분석의 최소 입자(granule)입니다.

주요 키 필드는 EBELN(PO 번호), EBELP(PO 아이템 번호), ETENR(스케줄 라인 번호)이며, 분석 관점에서 중요한 비키 필드는 EINDT(납품 예정일), SLFDT(통계적 납품일), MENGE(예정 수량), WEMNG(입고 완료 수량) 등입니다.

2. I_ScheduleLine CDS 뷰의 역할과 설계 의도

S/4HANA 시대로 넘어오면서 SAP는 EKET 같은 베이스 테이블을 직접 SELECT하는 방식을 권장하지 않고 있습니다. 대신 Virtual Data Model(VDM)이라 부르는 CDS 계층을 통해 데이터를 노출합니다. I_ScheduleLine(또는 정확히는 I_PurchaseOrderScheduleLine 계열)이 바로 EKET를 감싸는 인터페이스(Interface) 레이어의 CDS 뷰입니다.

SAP가 굳이 CDS 한 겹을 더 둔 이유는 크게 세 가지입니다.

  1. 의미 있는 필드명: EBELN이 아니라 PurchaseOrder, EINDT가 아니라 ScheduleLineDeliveryDate처럼 영어 비즈니스 용어로 통일
  2. Association 기반 모델링: PO 헤더·아이템·자재·플랜트·벤더와 그래프 형태로 연결되어 JOIN 없이 점(.) 표기로 탐색 가능
  3. 권한·확장성·릴리스 안정성: Behavior, Authority, Annotation을 한 곳에 묶고 업그레이드 시 호환성 보장

3. EKET 직접 조회 vs I_ScheduleLine — 무엇이 다른가

구분EKET 직접 SELECTI_ScheduleLine
필드명독일어 약어 (EBELN, EINDT)의미 기반 영문명 (PurchaseOrder, ScheduleLineDeliveryDate)
조인EKKO/EKPO/MARA 수동 JOINAssociation으로 점(.) 탐색
권한 체크AUTHORITY-CHECK 별도 구현Access Control(DCL)로 선언적 적용
릴리스 안정성테이블 구조 변경 시 영향인터페이스 계층이 흡수
S/4HANA Cloud접근 불가Released API 사용 가능

특히 S/4HANA Cloud(Public Edition)에서는 EKET를 ABAP 코드에서 직접 SELECT할 수 없습니다. Released 객체로 분류된 CDS 뷰만 허용되므로, 향후 Cloud 이행을 염두에 둔다면 처음부터 CDS 기반으로 작성해 두는 편이 일반적으로 권장됩니다.

4. I_ScheduleLine 주요 필드 해설

I_ScheduleLine 계열 뷰에서 자주 쓰이는 필드를 묶어 보면 다음과 같습니다. (시스템 버전에 따라 네이밍이 I_PurOrdScheduleLine, I_PurchaseOrderScheduleLineTP 등으로 분기되니 SE11이나 ADT에서 확인하시기 바랍니다.)

  • PurchaseOrder / PurchaseOrderItem / ScheduleLine — 키 3종 세트
  • ScheduleLineDeliveryDate — EINDT, 발주처에 약속된 납기일
  • StatisticalDeliveryDate — SLFDT, MRP·통계용 납기일
  • ScheduleLineOrderQuantity — MENGE, 해당 라인의 예정 수량
  • OpenQuantityInBaseUnit — 미입고 잔량
  • PurchasingDocumentDeletionCode — 삭제 플래그
  • _PurchaseOrder, _PurchaseOrderItem, _Material, _Plant — Association

5. 실전 예제 — 납기 지연 분석 3단계

시나리오: "오늘 기준으로 납기일이 지났는데도 아직 입고가 끝나지 않은 PO 스케줄 라인을 찾아 지연일수와 함께 표시하기"

1단계 — 기본 SELECT

REPORT zr_late_delivery_basic.

SELECT PurchaseOrder,
       PurchaseOrderItem,
       ScheduleLine,
       ScheduleLineDeliveryDate,
       ScheduleLineOrderQuantity,
       OpenQuantityInBaseUnit
  FROM I_PurchaseOrderScheduleLineTP
  WHERE ScheduleLineDeliveryDate < @sy-datum
    AND OpenQuantityInBaseUnit  > 0
  INTO TABLE @DATA(lt_overdue).

LOOP AT lt_overdue INTO DATA(ls_line).
  WRITE: / ls_line-purchaseorder,
           ls_line-scheduleline,
           ls_line-schedulelinedeliverydate,
           ls_line-openquantityinbaseunit.
ENDLOOP.

2단계 — Association 활용 + 지연일 계산

REPORT zr_late_delivery_assoc.

TYPES: BEGIN OF ty_result,
         po_number    TYPE ekko-ebeln,
         item         TYPE ekpo-ebelp,
         material     TYPE matnr,
         vendor       TYPE lifnr,
         plant        TYPE werks_d,
         due_date     TYPE eindt,
         open_qty     TYPE menge_d,
         delay_days   TYPE i,
       END OF ty_result.

DATA: lt_result TYPE TABLE OF ty_result.

SELECT sl~PurchaseOrder         AS po_number,
       sl~PurchaseOrderItem     AS item,
       item~Material            AS material,
       po~Supplier              AS vendor,
       item~Plant               AS plant,
       sl~ScheduleLineDeliveryDate AS due_date,
       sl~OpenQuantityInBaseUnit   AS open_qty,
       ( CAST( @sy-datum AS abap.dats ) - sl~ScheduleLineDeliveryDate ) AS delay_days
  FROM I_PurchaseOrderScheduleLineTP AS sl
  INNER JOIN sl~_PurchaseOrderItem    AS item
          ON item~PurchaseOrder     = sl~PurchaseOrder
         AND item~PurchaseOrderItem = sl~PurchaseOrderItem
  INNER JOIN sl~_PurchaseOrder        AS po
          ON po~PurchaseOrder = sl~PurchaseOrder
  WHERE sl~ScheduleLineDeliveryDate < @sy-datum
    AND sl~OpenQuantityInBaseUnit  > 0
    AND item~PurchasingDocumentItemCategory = '0'
  ORDER BY delay_days DESCENDING
  INTO TABLE @lt_result.

cl_demo_output=>display( lt_result ).

3단계 — Custom CDS Consumption View

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Overdue Purchase Order Schedule Lines'
@Metadata.allowExtensions: true
@VDM.viewType: #CONSUMPTION
@Analytics.dataCategory: #FACT

define view entity ZC_OverduePOSchedule
  as select from I_PurchaseOrderScheduleLineTP as ScheduleLine
  association [1..1] to I_PurchaseOrderItem as _Item
    on  _Item.PurchaseOrder     = ScheduleLine.PurchaseOrder
    and _Item.PurchaseOrderItem = ScheduleLine.PurchaseOrderItem
  association [1..1] to I_PurchaseOrder as _Header
    on  _Header.PurchaseOrder = ScheduleLine.PurchaseOrder
{
  key ScheduleLine.PurchaseOrder,
  key ScheduleLine.PurchaseOrderItem,
  key ScheduleLine.ScheduleLine,
      _Header.Supplier             as SupplierID,
      _Item.Material               as MaterialID,
      _Item.Plant                  as PlantID,
      ScheduleLine.ScheduleLineDeliveryDate    as DueDate,
      ScheduleLine.OpenQuantityInBaseUnit      as OpenQuantity,
      cast( dats_days_between(
              ScheduleLine.ScheduleLineDeliveryDate,
              $session.system_date ) as abap.int4 )  as DelayDays,
      _Item, _Header
}
where ScheduleLine.OpenQuantityInBaseUnit > 0
  and ScheduleLine.ScheduleLineDeliveryDate < $session.system_date;

Consumption 뷰는 ALV, Fiori Elements List Report, RAP Query 등 어디서든 재사용할 수 있고, 권한 체크는 상위 인터페이스 뷰의 DCL을 그대로 상속받습니다.

6. CDS 뷰 확장 — Metadata Extension과 VDM 패턴

I_ScheduleLine 같은 SAP 표준 뷰를 직접 수정할 수는 없지만, Metadata Extension이나 CDS View Extension으로 안전하게 확장할 수 있습니다.

@Metadata.layer: #CUSTOMER
annotate view I_PurchaseOrderScheduleLineTP with
{
  @UI.lineItem: [ { position: 10, label: 'PO Number' } ]
  PurchaseOrder;

  @UI.lineItem: [ { position: 20, label: 'Delivery Date' } ]
  ScheduleLineDeliveryDate;
}

VDM 레이어 구조 4단계:

  • Basic (B_) — 테이블 1:1 매핑
  • Composite (R_) — 여러 Basic을 합쳐 비즈니스 의미 부여
  • Interface (I_) — 외부에 노출되는 안정적 계약
  • Consumption (C_) — UI/리포트 등 최종 소비처

7. 자주 하는 실수와 해결법

Q1. S/4HANA Cloud에서 "SELECT FROM eket" 하니 syntax error가 납니다.

Public Cloud에서는 Released 객체만 허용됩니다. I_PurchaseOrderScheduleLineTP가 Released 상태인지 확인하고, EKET 대신 그 뷰를 사용하세요.

Q2. 동일 PO 아이템인데 결과 행이 중복으로 나옵니다.

스케줄 라인이 분할되어 EKET에 여러 레코드가 존재하는 정상 상황입니다. PO 아이템 단위로 보고 싶다면 SUM(OpenQuantityInBaseUnit)으로 GROUP BY 하거나, I_PurchaseOrderItem의 잔량 필드를 사용하세요.

Q3. ScheduleLineDeliveryDate와 StatisticalDeliveryDate 중 무엇으로 지연을 판단해야 하나요?

운영(Operations) 관점의 지연 분석은 EINDT 기반의 ScheduleLineDeliveryDate, 계획(Planning) 관점의 가용성 분석은 SLFDT 기반의 StatisticalDeliveryDate를 사용하는 편이 자연스럽습니다.

Q4. Authorization 에러가 발생합니다.

@AccessControl.authorizationCheck: #CHECK가 설정된 뷰는 DCL을 통해 권한 객체 M_BEST_* 시리즈를 확인합니다. 사용자에게 구매 조직·플랜트별 권한이 부여되어 있는지 SU01/PFCG에서 점검하세요.

8. 정리 및 실무 적용 팁

EKET와 I_ScheduleLine의 관계를 한 줄로 요약하면 "원본 테이블의 키와 수치를 그대로 가지고 있되, 비즈니스 친화적인 이름·Association·권한 모델을 입힌 안정적 인터페이스"입니다. 실무에서 다음 원칙을 따르는 편이 일반적으로 권장됩니다.

  • 새로운 보고서·Fiori 앱은 EKET 직접 SELECT 대신 I_ 계열 인터페이스 뷰로 시작
  • 비즈니스 로직은 Z Consumption CDS 뷰에 응축하고, ABAP은 데이터 표시·이벤트 처리만
  • 지연일·잔량 같은 파생 값은 가능하면 CDS 내부에서 계산해 HANA로 푸시다운
  • 표준 뷰는 절대 수정하지 말고 Metadata Extension만 사용
  • S/4HANA Cloud 이행 가능성을 염두에 두고 Released 객체 기반으로 작성

납기 지연 분석은 야간 배치로 결과를 Z 테이블에 적재해 두고, 주간 알림은 그 결과를 읽어 메일·Teams로 발송하는 구조가 안정적입니다. CDS 뷰는 실시간 조회용으로 두고, 무거운 집계는 CDS View with Parameters 또는 Analytics용 Cube 뷰(@Analytics.dataCategory: #CUBE)로 별도 분리하면 시스템 부하를 줄일 수 있습니다.

댓글 0

아직 댓글이 없습니다.