RBKP를 직접 쓰면 안 되는 이유
SAP S/4HANA 환경에서 공급업체 인보이스(Vendor Invoice) 데이터를 다룰 때 가장 흔하게 마주치는 유혹은 RBKP 테이블을 직접 SELECT하는 방식입니다. RBKP는 MM-IV(Logistics Invoice Verification) 모듈에서 인보이스 헤더를 저장하는 테이블로 오랫동안 사용되어 왔지만, 최신 S/4HANA에서는 직접 접근을 권장하지 않습니다.
- RBKP는 결제 상태, 워크플로 상태, 차단 사유 등이 별도 테이블(RSEG, BKPF, BSEG)에 분산되어 있어 한 번의 SELECT만으로는 비즈니스 의미를 완성할 수 없습니다.
- S/4HANA Cloud에서는 일부 칼럼이 release되지 않아 ATC 경고가 발생할 수 있습니다.
- 코드 단위 보안(DCL)과 권한 체크가 자동으로 적용되지 않습니다.
- 릴리스 간 구조 변경 시 직접 SQL이 깨질 위험이 있습니다.
I_SupplierInvoice는 RBKP를 기반으로 하되 비즈니스 친화적인 필드명을 갖고, 어소시에이션(association)을 통해 FI 회계전표, 공급업체 마스터, 회사코드 등과 연결됩니다.
I_SupplierInvoice 구조 — 주요 필드
I_SupplierInvoice는 Basic 계층의 인터페이스 뷰로 인보이스 한 건당 한 행(헤더 단위)을 반환합니다.
SupplierInvoice: 인보이스 번호 (RBKP-BELNR)FiscalYear: 회계연도 (RBKP-GJAHR)CompanyCode: 회사코드 (RBKP-BUKRS)DocumentDate: 문서일자 (RBKP-BLDAT)PostingDate: 전기일자 (RBKP-BUDAT)InvoicingParty: 인보이스 발행 공급업체 (RBKP-LIFNR)InvoiceGrossAmount: 총액 (RBKP-RMWWR)SupplierInvoiceStatus: 인보이스 상태 (RBKP-RBSTAT)SupplierInvoiceIsBlockedForPayment: 지급 차단 플래그 (RBKP-ZLSPR)
RBKP vs I_SupplierInvoice 필드 매핑
- BELNR → SupplierInvoice (인보이스 번호)
- GJAHR → FiscalYear (회계연도)
- BUKRS → CompanyCode (회사코드)
- LIFNR → InvoicingParty (공급업체)
- BLDAT → DocumentDate (문서일자)
- BUDAT → PostingDate (전기일자)
- RMWWR → InvoiceGrossAmount (총액)
- ZLSPR → SupplierInvoiceIsBlockedForPayment (지급 차단)
- RBSTAT → SupplierInvoiceStatus (인보이스 상태)
기본 조회 — 미결 인보이스 필터링
먼저 안티패턴부터 살펴봅니다. RBKP를 직접 SELECT하면 동작은 하지만 권장되지 않습니다.
" 안티패턴: RBKP 직접 접근
SELECT belnr, gjahr, bukrs, lifnr, bldat, rmwwr, rbstat, zlspr
FROM rbkp
INTO TABLE @DATA(lt_rbkp_raw)
WHERE bukrs = '1010'
AND budat >= '20260101'
AND rbstat = '5'. " 5 = Posted (의미가 코드에 묻혀 있음)동일한 작업을 I_SupplierInvoice로 다시 작성하면 의도가 명확해집니다.
" 권장 패턴: I_SupplierInvoice CDS View 사용
SELECT SupplierInvoice,
FiscalYear,
CompanyCode,
InvoicingParty,
PostingDate,
InvoiceGrossAmount,
DocumentCurrency,
SupplierInvoiceIsBlockedForPayment
FROM I_SupplierInvoice
INTO TABLE @DATA(lt_invoice)
WHERE CompanyCode = '1010'
AND PostingDate >= '20260101'
AND SupplierInvoiceIsBlockedForPayment = @abap_true.FI 문서번호 연계 — I_SupplierInvoiceItem
라인 정보는 I_SupplierInvoiceItem에서 제공됩니다. 헤더의 어소시에이션 _AccountingDocumentHeader를 통해 FI 전표로 즉시 연결할 수 있습니다.
SELECT h~SupplierInvoice,
h~FiscalYear,
h~InvoicingParty,
h~InvoiceGrossAmount AS HeaderAmount,
i~SupplierInvoiceItem,
i~PurchaseOrder,
i~GLAccount,
i~SupplierInvoiceItemAmount
FROM I_SupplierInvoice AS h
INNER JOIN I_SupplierInvoiceItem AS i
ON h~SupplierInvoice = i~SupplierInvoice
AND h~FiscalYear = i~FiscalYear
INTO TABLE @DATA(lt_invoice_full)
WHERE h~CompanyCode = @p_bukrs
AND h~PostingDate BETWEEN @p_from AND @p_to.공급업체별 인보이스 집계 쿼리
월별 정산이나 미지급금 리포트를 만들 때는 공급업체별 합계가 필요합니다.
SELECT InvoicingParty,
DocumentCurrency,
COUNT( * ) AS InvoiceCount,
SUM( InvoiceGrossAmount ) AS TotalAmount,
MIN( PostingDate ) AS OldestPostingDate
FROM I_SupplierInvoice
WHERE CompanyCode = @p_bukrs
AND SupplierInvoiceIsBlockedForPayment = @abap_true
GROUP BY InvoicingParty, DocumentCurrency
HAVING SUM( InvoiceGrossAmount ) > @p_threshold
ORDER BY TotalAmount DESCENDING
INTO TABLE @DATA(lt_agg).성능 고려사항 — 인덱스와 파티셔닝
- 필드 프로젝션 최소화: 필요한 칼럼만 SELECT합니다. SELECT *는 컬럼 스토어에 비효율적입니다.
- WHERE 절에 키 필드 우선: CompanyCode, FiscalYear, SupplierInvoice 순으로 필터를 걸면 파티셔닝과 잘 맞습니다.
- 어소시에이션 lazy 평가: 어소시에이션 필드는 SELECT 절에 등장할 때만 join이 실행됩니다.
- 패키지 크기 제어: 대량 조회 시 PACKAGE SIZE로 메모리 폭주를 막습니다.
핵심 한 줄
RBKP를 직접 읽지 말고 I_SupplierInvoice + I_SupplierInvoiceItem + 어소시에이션 기반 FI 연계로 작성하면, 의미가 명확하고 권한과 릴리스 호환성이 함께 따라옵니다.
댓글 0
아직 댓글이 없습니다.