SAP

FKREL 확인 없이 청구 막히는 3가지 이유 #shorts #SAP #SAP

▶ YouTube에서 보기

이 글이 답하는 질문

출고전기까지 끝난 납품전표인데 VF01을 열면 "청구 대상 전표가 없습니다"가 뜬다. 창고는 물건을 보냈고 재고도 빠졌는데 매출이 안 잡히는 상황이다. 이 글에서는 그 원인의 8할을 차지하는 항목범주(Item Category)의 청구관련 지시자(Billing Relevance, TVAP-FKREL)를 중심으로, 설정이 청구 생성을 어디서 막는지와 진단·복구 절차를 다룬다.

  • 청구관련 지시자 값(공란/A/B/C/D/F/I 등)이 각각 어떤 청구 트리거를 의미하는지 구분한다
  • 납품은 완료인데 VF04 청구기일목록에 안 뜨는 전표를 SQL/ABAP으로 역추적한다
  • 항목범주 복사 시 실무에서 반복되는 미청구 사고의 재발 방지 체크를 자동화한다

이 글을 보기 전에

SD 판매오더 → 납품 → 출고전기 → 청구로 이어지는 전표 흐름과 VA01/VL01N/VF01 화면을 한 번이라도 돌려본 경험을 가정한다. 항목범주 결정(판매전표유형 + 항목범주그룹 + 용도 + 상위항목범주)과 복사관리(Copy Control)라는 단어가 낯설지 않으면 충분하다. ABAP은 Open SQL SELECT를 읽을 수 있는 정도면 된다.

테스트 환경과 확인 도구

검증 환경은 SAP S/4HANA 2022 On-Premise(SD-BIL, SD-SLS)이며, ECC 6.0 EHP8 기준 차이는 본문에 따로 표기했다. 화면 조작은 SAP GUI 7.70, 데이터 조회는 SE16N과 ADT(ABAP Development Tools) Eclipse 플러그인을 사용했다.

  • 커스터마이징: VOV7(항목범주 정의), VOV4(항목범주 결정), VTFL(납품 → 청구 복사관리), VTFA(오더 → 청구 복사관리)
  • 운영 트랜잭션: VA03, VL03N, VF01, VF04(청구기일목록), VF05(청구전표 목록)
  • 테이블: TVAP(판매 항목범주), TVLP(납품 항목범주), VBAP/LIPS/VBFA, VKDFS(청구기일 인덱스)
  • S/4HANA 유의: 상태 테이블 VBUK/VBUP가 제거되고 상태 필드가 VBAK/VBAP/LIKP/LIPS로 흡수됐다. ECC 코드를 그대로 옮기면 덤프가 난다(SAP Note 검색어: S4TWL Data Model Changes in SD).

핵심 개념 — 청구관련 지시자가 결정하는 것

청구전표는 "납품이 끝났으니 자동으로" 생기는 물건이 아니다. 청구기일목록(VF04)에 올라오는 후보는 항목 단위로 계산되고, 그 항목이 후보가 될 자격이 있는지를 최종 판정하는 스위치가 항목범주의 청구관련 지시자다. 비유하자면 납품전표는 "출고 완료" 도장이 찍힌 서류고, 청구관련 지시자는 그 서류를 경리팀 결재함에 넣을지 결정하는 분류 규칙이다. 도장이 아무리 선명해도 분류 규칙이 "이 서류는 경리 대상 아님"이면 결재함에는 영원히 들어가지 않는다.

흐름을 도식으로 보면 이렇다.

판매오더 항목(VBAP-PSTYV)
      │  → TVAP-FKREL (청구관련 지시자) 조회
      ▼
[ 공란 ] ──► 청구 후보 아님. VF04에 영원히 안 뜸
[  A   ] ──► 납품기준 청구. 출고전기(LIPS-WBSTA='C') 후 후보 등록
[ B/C  ] ──► 오더기준 청구. 납품 없이도 VF01 가능
[  D   ] ──► 견적송장 전용. 실물 청구 생성 안 됨
[  F   ] ──► 오더기준 + 송장접수수량(3자 직송, MIRO 후)
[  I   ] ──► 청구계획 기준(계약·기성)
      ▼
복사관리(VTFL/VTFA) 요구조건 루틴 통과 → VKDFS 인덱스 등록 → VF04 노출

여기서 자주 오해되는 지점이 두 가지다. 첫째, 납품 항목범주(LIPS-PSTYV, TVLP)가 아니라 선행 판매오더 항목범주(VBAP-PSTYV, TVAP)의 FKREL이 납품기준 청구 여부를 좌우한다. 납품 항목범주만 뒤지다가 원인을 못 찾는 경우가 많다. 둘째, FKREL이 정상이어도 복사관리의 복사요구조건 루틴(납품기준 항목 루틴 004 계열)이 출고전기 완료·수량 0 여부를 다시 검사한다. 즉 관문이 두 개다.

대표값 정리는 아래와 같다. 릴리스와 산업 솔루션에 따라 목록에 값이 추가될 수 있으므로 실제 시스템의 F4 도움말을 함께 확인하는 것을 권장한다.

의미대표 사용처
(공란)청구 대상 아님무상 제공 항목, 텍스트 항목, BOM 상위 더미
A납품기준 청구재고 판매 표준 항목(TAN)
B / C오더기준(오더수량 / 목표수량)서비스 판매, 계약 콜오프
D견적송장 전용수출 프로포마, 전표흐름 미갱신
F오더기준 + 송장접수수량3자 직송(TAS)
I청구계획 기준임대, 기성 청구

실전 예제 3단계

배경 시나리오는 이렇게 잡았다. 산업용 여과장치를 만드는 가상 회사 한서정공이 판촉용 항목범주 ZFRE(무상 샘플)를 복사해 유상 프로모션 항목범주 ZPRM을 신설했다. 복사 원본이 무상이었으니 FKREL은 공란이었고, 담당자는 가격결정만 손보고 이관했다. 3주 뒤 자재 HF-3200 고압필터 납품 412건, 약 6.4억 원이 미청구로 쌓였다.

1단계 — 특정 납품전표의 청구 차단 지점 찾기

먼저 문제가 된 납품전표 한 건에서 선행 오더 항목범주와 FKREL을 한 번에 뽑는다. GUI로는 VL03N → 항목 → 전표흐름으로 오더를 찾고 VA03 → 항목상세 → 판매A 탭에서 항목범주를 확인한 뒤 VOV7로 들어가면 되지만, 건수가 많으면 조회가 빠르다.

REPORT zsd_billrel_probe.

PARAMETERS p_vbeln TYPE lips-vbeln OBLIGATORY.

SELECT di~vbeln, di~posnr, di~matnr, di~lfimg,
       di~wbsta AS gi_status,
       di~vgbel AS sales_doc, di~vgpos AS sales_item,
       si~pstyv AS order_item_cat,
       ic~fkrel AS billing_relevance
  FROM lips AS di
  LEFT OUTER JOIN vbap AS si ON si~vbeln = di~vgbel
                            AND si~posnr = di~vgpos
  LEFT OUTER JOIN tvap AS ic ON ic~pstyv = si~pstyv
  WHERE di~vbeln = @p_vbeln
  INTO TABLE @DATA(lt_probe).

LOOP AT lt_probe INTO DATA(ls).
  WRITE: / ls-posnr, ls-matnr, ls-order_item_cat,
           '| FKREL=', ls-billing_relevance,
           '| GI=',    ls-gi_status.
ENDLOOP.

출력에서 FKREL= 뒤가 비어 있으면 원인 확정이다. D가 나오면 견적송장 전용이라 실물 청구는 애초에 생성되지 않는다.

2단계 — 미청구 납품 일괄 추출과 원인 분류(운영 배치용)

사고는 보통 한 건이 아니라 기간 단위로 터진다. 출고전기는 됐는데 청구전표(VBFA 후속 전표유형 M)가 없는 항목만 골라 원인 코드를 붙이고 애플리케이션 로그로 남긴다.

CLASS lcl_unbilled DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_row,
             vbeln  TYPE lips-vbeln,
             posnr  TYPE lips-posnr,
             matnr  TYPE lips-matnr,
             pstyv  TYPE vbap-pstyv,
             fkrel  TYPE tvap-fkrel,
             reason TYPE char40,
           END OF ty_row.
    METHODS collect IMPORTING iv_from TYPE dats iv_to TYPE dats
                    RETURNING VALUE(rt) TYPE STANDARD TABLE OF ty_row WITH EMPTY KEY.
ENDCLASS.

CLASS lcl_unbilled IMPLEMENTATION.
  METHOD collect.
    SELECT di~vbeln, di~posnr, di~matnr, si~pstyv, ic~fkrel,
           dh~faksk AS hdr_bill_block, di~wbsta
      FROM lips AS di
      INNER JOIN likp AS dh ON dh~vbeln = di~vbeln
      LEFT OUTER JOIN vbap AS si ON si~vbeln = di~vgbel AND si~posnr = di~vgpos
      LEFT OUTER JOIN tvap AS ic ON ic~pstyv = si~pstyv
      WHERE dh~wadat_ist BETWEEN @iv_from AND @iv_to
        AND NOT EXISTS ( SELECT * FROM vbfa AS fl
                          WHERE fl~vbelv   = di~vbeln
                            AND fl~posnv   = di~posnr
                            AND fl~vbtyp_n = 'M' )
      INTO TABLE @DATA(lt_raw).

    LOOP AT lt_raw INTO DATA(ls).
      DATA(lv_reason) = COND char40(
        WHEN ls-fkrel IS INITIAL      THEN 'FKREL 공란: 항목범주 청구대상 아님'
        WHEN ls-fkrel = 'D'           THEN 'FKREL D: 견적송장 전용'
        WHEN ls-wbsta <> 'C'          THEN '출고전기 미완료'
        WHEN ls-hdr_bill_block IS NOT INITIAL THEN '납품헤더 청구보류'
        ELSE '복사관리/요구조건 루틴 점검 필요' ).

      APPEND VALUE #( vbeln = ls-vbeln posnr = ls-posnr matnr = ls-matnr
                      pstyv = ls-pstyv fkrel = ls-fkrel
                      reason = lv_reason ) TO rt.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

원인 코드가 붙으면 대응이 갈린다. FKREL 공란은 커스터마이징 수정 + 납품 재처리, 출고전기 미완료는 물류팀 이슈, 청구보류는 VL02N/VA02에서 보류 해제로 끝난다.

3단계 — CDS 뷰 + 야간 배치로 재발 감시

운영에서는 조회 자체를 CDS 뷰로 올려 Fiori 분석 앱과 공유하고, 배치는 권한 체크와 패키지 처리를 붙인다. 아래는 S/4HANA 2021 이상 뷰 엔티티 문법이다.

@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: '미청구 납품항목 감시'
define view entity ZI_UnbilledDelivItem
  as select from lips as DelivItem
    inner join   likp as DelivHdr  on  DelivHdr.vbeln = DelivItem.vbeln
    left outer join vbap as OrderItem on OrderItem.vbeln = DelivItem.vgbel
                                     and OrderItem.posnr = DelivItem.vgpos
    left outer join tvap as ItemCat   on ItemCat.pstyv  = OrderItem.pstyv
{
  key DelivItem.vbeln          as DeliveryDocument,
  key DelivItem.posnr          as DeliveryItem,
      DelivHdr.vkorg           as SalesOrganization,
      DelivHdr.wadat_ist       as ActualGoodsIssueDate,
      DelivItem.matnr          as Material,
      OrderItem.pstyv          as OrderItemCategory,
      ItemCat.fkrel            as BillingRelevance,
      case when ItemCat.fkrel = '' then 'NO_BILL_REL'
           when ItemCat.fkrel = 'D' then 'PROFORMA_ONLY'
           when DelivItem.wbsta <> 'C' then 'GI_OPEN'
           else 'CHECK_COPY_CONTROL' end as DiagnosisCode
}
where DelivItem.lfimg > 0

성능 관점에서 조회 기준일(wadat_ist)과 판매조직을 반드시 조건에 넣고, 전수 스캔이 필요하면 청구기일 인덱스 VKDFS를 함께 활용하는 편이 안전하다. 이관 전 회귀 테스트로는 "신규 항목범주는 FKREL이 공란이면 승인 필요"라는 규칙을 ABAP Unit으로 고정해 두면, 복사로 만든 항목범주가 조용히 넘어가는 사고를 막을 수 있다.

자주 만나는 함정과 삽질 노트

  • Q1. FKREL을 A로 고쳤는데 기존 납품이 여전히 VF04에 안 뜬다. 커스터마이징 변경은 이미 생성된 전표에 소급되지 않는다. 상태와 청구기일 인덱스가 전표 생성 시점 값으로 굳어 있기 때문이다. 실무에서는 납품 취소 후 재생성, 또는 판매오더 항목 재저장(VA02에서 아무 필드 터치 후 저장)으로 인덱스를 갱신하는 방식을 쓴다.
  • Q2. FKREL은 A인데도 VF01에서 "청구 대상 전표 없음"이 뜬다. 관문이 두 개라고 했던 지점이다. VTFL에서 납품유형 → 청구유형 조합 자체가 없으면 복사가 성립하지 않는다. 항목 레벨의 청구수량 필드가 공란이거나 복사요구조건 루틴이 출고전기 미완료를 걸러내는 경우도 흔하다.
  • Q3. 무상 샘플인데 청구가 생기지 않는다. 이건 사고가 아니라 정상 동작이다. 무상 항목범주는 FKREL이 공란으로 설계되며, 매출은 없지만 원가는 잡아야 하므로 계정결정과 원가 전기 설정을 별도로 본다.
  • Q4. 견적송장은 나오는데 실제 세금계산서가 안 나온다. FKREL이 D면 견적송장 전용이라 전표흐름과 청구상태를 갱신하지 않는다. 실물 청구가 필요하면 항목범주를 분리하거나 별도 항목범주를 결정하도록 VOV4를 손봐야 한다.
  • Q5. 부분납품에서 두 번째 청구가 안 잡힌다. 항목 청구상태(S/4는 LIPS-FKSTA, ECC는 VBUP-FKSTA)가 C로 완료 처리됐는지 본다. VTFL 청구수량 지시자 설정이 잘못되면 첫 청구에서 전량 완료로 닫히는 사례가 생긴다.

더 파볼 주제

  • 복사관리 VTFL/VTFA의 요구조건·데이터전송 로직을 직접 읽어 청구 후보 판정 흐름 추적하기
  • 3자 직송(FKREL=F)과 MM 송장검증(MIRO) 연동에서 청구 시점이 밀리는 구조
  • 청구계획(FKREL=I) 기반 임대·기성 청구와 기간 청구 자동화
  • S/4HANA 상태 데이터 모델 변경(VBUK/VBUP 제거)이 기존 커스텀 SD 리포트에 미치는 영향과 리팩터링
  • Fiori "청구전표 생성" 앱과 VF04 백그라운드 잡의 실행 차이

댓글 0

아직 댓글이 없습니다.