SAP

F2 vs G2 vs L2 청구유형 뭐가 다를까 #shorts #SAP #SAP

개요 — 이 글에서 얻어갈 것

SD 청구(Billing) 문서를 처음 접하면 F2, G2, L2라는 코드가 같은 화면(VF01)에서 만들어지는데도 회계에 미치는 방향이 정반대라는 점 때문에 혼란이 생깁니다. 이 글은 세 가지 표준 청구유형이 어떤 업무 트리거로 생성되는지, 그리고 FI 전표의 차변/대변이 어떻게 갈리는지를 카피 컨트롤 설정과 함께 단계별로 정리합니다.

  • F2(청구서), G2(대변메모), L2(차변메모)의 업무적 발생 시점 구분
  • 청구유형별 FI 계정전기 방향(고객 계정 차변 vs 대변) 이해
  • 카피 컨트롤(VTFA/VTFL)이 선행 문서와 청구유형을 연결하는 구조 파악
  • 문서 흐름을 코드로 판별하고 검증 로직을 붙이는 실전 예제 3단계

미리 알아두면 좋은 것

SD 판매 오더(VA01)와 납품(VL01N)의 기본 흐름, 그리고 FI에서 차변/대변이 무엇을 의미하는지 정도만 알고 있으면 충분합니다. ABAP 예제가 나오지만 SELECT 문과 내부 테이블을 읽을 수 있는 수준이면 따라올 수 있습니다. VBRK/VBRP 테이블을 조회해 본 경험이 있다면 더 빠르게 이해됩니다.

환경과 준비물

이 글의 화면 경로와 코드는 SAP S/4HANA 2023 (On-Premise) 기준이며, ECC 6.0에서도 청구유형 구조 자체는 거의 동일하게 적용됩니다(일반적으로 트랜잭션 코드와 테이블 구조가 그대로 유지됩니다). 실습에 필요한 것은 다음과 같습니다.

  • 트랜잭션: VOFA(청구유형 정의), VTFA(오더→청구 카피 컨트롤), VTFL(납품→청구 카피 컨트롤), VF01/VF03
  • 참조 테이블: VBRK(청구 헤더), VBRP(청구 품목), VBFA(문서 흐름)
  • 개발 실습용: SE38 또는 ADT(Eclipse), 커스텀 테이블 생성 권한(SE11)
  • S/4HANA Cloud Public Edition에서는 VOFA 직접 수정 대신 SSCUI 기반 구성을 사용하므로, 이 글의 IMG 경로는 On-Premise/Private Edition 기준으로 읽어 주세요.

핵심 개념 — 세 문서는 '돈의 방향'이 다르다

가장 쉬운 비유는 가게 사장의 외상 장부입니다. 손님에게 물건을 팔고 "받을 돈"을 적는 것이 F2(청구서, Invoice)입니다. 그런데 물건 일부가 불량이라 값을 깎아주기로 했다면 장부에서 받을 돈을 줄여 적어야 하는데, 이것이 G2(대변메모, Credit Memo)입니다. 반대로 처음에 단가를 잘못 낮게 청구했음을 발견해 추가로 더 받아야 한다면 L2(차변메모, Debit Memo)를 발행합니다.

FI 관점에서 방향을 표로 정리하면 다음과 같습니다.

청구유형업무 트리거고객(채권) 계정매출 계정채권 잔액
F2 청구서납품 완료 후 정상 대금 청구차변(Debit)대변(Credit)증가
G2 대변메모가격 오류 정정(과다 청구), 품질 보상, 반품 없는 감액대변(Credit)차변(Debit, 매출 차감)감소
L2 차변메모과소 청구 정정, 추가 비용(운임·수수료) 후청구차변(Debit)대변(Credit)증가

생성 경로도 다릅니다. F2는 일반적으로 납품(Delivery)을 참조해 만들어지는 납품 기반 청구입니다. 반면 G2와 L2는 물류가 개입하지 않는 순수 금액 정정이므로, 먼저 대변메모 요청(CR, 문서유형) 또는 차변메모 요청(DR)이라는 판매 문서를 만들고 이를 오더 기반 청구로 전환합니다. 즉 문서 흐름이 이렇게 갈립니다.

정상 흐름: 판매오더(OR) → 납품(LF) → F2 → FI 전표(채권 차변)
감액 흐름: 대변메모요청(CR) → G2 → FI 전표(채권 대변)
증액 흐름: 차변메모요청(DR) → L2 → FI 전표(채권 차변)

이 연결 고리를 실제로 묶어주는 것이 카피 컨트롤입니다. VTFL에서 "LF → F2" 조합이, VTFA에서 "CR → G2", "DR → L2" 조합이 정의되어 있어야만 VF01에서 참조 생성이 가능합니다. 카피 컨트롤에는 복사 요구사항(Copying Requirement) 루틴과 가격결정 유형(Pricing Type)이 함께 걸려 있어, 예를 들어 G2 생성 시 가격을 재계산할지(B) 원본 그대로 복사할지(G)가 여기서 결정됩니다. CR/DR 문서유형에는 표준 설정상 청구 차단(Billing Block)이 기본으로 걸려 있는 경우가 많아, 담당자가 승인(차단 해제)해야 비로소 G2/L2를 만들 수 있다는 점도 중요한 통제 장치입니다.

기술적으로는 VBRK-VBTYP(문서 범주)가 F2는 'M', G2는 'O', L2는 'P'로 저장되고, 품목의 차대변 지시자는 VBRP/전표의 SHKZG로 넘어갑니다. 화면에서 G2 금액이 양수로 보여도 회계에서는 반대 방향으로 전기되는 이유가 이 지시자 때문입니다.

실전 코드 3단계 — 문서 흐름 판별부터 검증 로직까지

가상의 제조사 "한빛정밀"이 청구 문서를 유형별로 분석하고, 대변메모 남발을 막는 검증 로직을 붙이는 시나리오로 진행합니다. 아래 코드는 모두 창작 예제이며 표준 문서의 예제를 복사한 것이 아닙니다.

1단계 — 기본: 청구유형별 채권 영향 분류 리포트

VBRK를 읽어 문서 범주(VBTYP)로 채권 증감 방향을 판별합니다. 핵심은 "유형 코드"가 아니라 범주로 분기해야 커스텀 청구유형(ZF2 등)도 함께 잡힌다는 점입니다.

REPORT zhb_billing_direction.

PARAMETERS: p_kunag TYPE kunag OBLIGATORY,
            p_fkdat TYPE fkdat DEFAULT sy-datum.

SELECT vbeln, fkart, vbtyp, netwr, waerk
  FROM vbrk
  WHERE kunag  = @p_kunag
    AND fkdat <= @p_fkdat
  INTO TABLE @DATA(lt_bill).

LOOP AT lt_bill INTO DATA(ls_bill).
  DATA(lv_dir) = SWITCH string( ls_bill-vbtyp
    WHEN 'M' THEN |채권 증가(차변)|   " F2 계열 청구서
    WHEN 'P' THEN |채권 증가(차변)|   " L2 계열 차변메모
    WHEN 'O' THEN |채권 감소(대변)|   " G2 계열 대변메모
    ELSE          |기타/취소 문서| ).
  WRITE: / ls_bill-vbeln, ls_bill-fkart,
           ls_bill-netwr CURRENCY ls_bill-waerk, lv_dir.
ENDLOOP.

이 리포트를 돌려 보면 G2 문서도 NETWR이 양수로 저장되어 있음을 확인할 수 있습니다. 방향은 금액 부호가 아니라 VBTYP(그리고 FI 전표의 SHKZG)이 결정합니다.

2단계 — 실무: 사유 코드 기반 대변메모 통제 + 로깅

한빛정밀은 "오더 사유(AUGRU) 없이 만든 CR은 청구되면 안 된다"는 내부 통제를 겁니다. 사유별 허용 청구유형을 커스텀 테이블 ZHB_REASON_MAP(필드: AUGRU, FKART_ALLOW)에 담고, VOFM 복사 요구사항 루틴(예: 951번)을 만들어 VTFA의 CR→G2 조합에 지정합니다.

FORM bedingung_pruefen_951.
  " VTFA: CR -> G2 복사 요구사항 (창작 예제)
  DATA lv_allowed TYPE fkart.

  sy-subrc = 0.

  IF vbak-augru IS INITIAL.
    sy-subrc = 4.
    PERFORM vbfs_hinzufuegen USING vbak-vbeln '000000'
            'ZHB_BILL' 'E' '010' space.   " 오더 사유 누락
    RETURN.
  ENDIF.

  SELECT SINGLE fkart_allow FROM zhb_reason_map
    WHERE augru = @vbak-augru
    INTO @lv_allowed.

  IF sy-subrc <> 0 OR lv_allowed <> vbrk-fkart.
    sy-subrc = 4.
    PERFORM vbfs_hinzufuegen USING vbak-vbeln '000000'
            'ZHB_BILL' 'E' '011' vbak-augru. " 사유-유형 불일치
  ENDIF.
ENDFORM.

루틴이 sy-subrc = 4를 반환하면 해당 오더는 청구 대상에서 제외되고, 메시지는 청구 로그(VF01/VF04의 로그 화면, 내부적으로 VBFS)에 남아 담당자가 원인을 추적할 수 있습니다. 에러를 조용히 삼키지 않고 반드시 로그에 남기는 것이 실무 포인트입니다.

3단계 — 프로덕션: CDS로 순채권 흐름 집계 + 단위 테스트 가능한 구조

월말 결산 때 "이 고객의 청구-대변-차변 순액"을 빠르게 보려면 루프 대신 CDS 뷰로 DB 계층에서 부호를 통일해 집계하는 편이 성능상 유리합니다.

@AbapCatalog.sqlViewName: 'ZHBNETBILL'
@AccessControl.authorizationCheck: #CHECK
define view ZHB_I_NetBilling as select from vbrk {
  key kunag,
  key waerk,
  sum( case vbtyp
         when 'O' then netwr * -1   // G2: 채권 감소
         else netwr                  // F2/L2: 채권 증가
       end ) as net_receivable_effect
}
where vbtyp in ('M','O','P')
  and fksto = ''                     // 취소된 청구 제외
group by kunag, waerk

이를 소비하는 ABAP 클래스는 조회 로직을 인터페이스 뒤로 숨겨 테스트 더블을 주입할 수 있게 설계합니다.

CLASS zhb_cl_net_billing DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    METHODS get_net FOR TESTING RAISING zcx_hb_billing.
    METHODS get_net_effect
      IMPORTING iv_kunag        TYPE kunag
      RETURNING VALUE(rv_netwr) TYPE netwr.
ENDCLASS.

CLASS zhb_cl_net_billing IMPLEMENTATION.
  METHOD get_net_effect.
    AUTHORITY-CHECK OBJECT 'V_VBRK_FKA'
      ID 'FKART' FIELD 'F2'
      ID 'ACTVT' FIELD '03'.
    IF sy-subrc <> 0.
      RAISE EXCEPTION NEW zcx_hb_billing( ).
    ENDIF.
    SELECT SINGLE net_receivable_effect
      FROM zhb_i_netbilling
      WHERE kunag = @iv_kunag
      INTO @rv_netwr.
  ENDMETHOD.
ENDCLASS.

ABAP Unit에서는 CDS 테스트 더블 프레임워크(CL_CDS_TEST_ENVIRONMENT)로 ZHB_I_NetBilling에 가짜 데이터를 심어, F2 100 + L2 20 − G2 30 = 90이 나오는지 검증하는 식으로 회귀 테스트를 구성할 수 있습니다. 권한 체크(AUTHORITY-CHECK)까지 포함해야 청구 데이터라는 민감 정보 접근이 통제됩니다.

흔한 실수와 트러블슈팅 FAQ

Q1. G2 대변메모와 반품 대변메모(RE)는 뭐가 다른가요?
G2는 물건이 돌아오지 않는 순수 금액 보정(가격 오류, 보상)이고, 반품 대변메모는 반품 오더 → 반품 입고라는 물류 흐름을 거친 뒤 발행됩니다. 재고가 움직였다면 반품 흐름, 돈만 움직인다면 CR→G2가 일반적으로 맞는 선택입니다.

Q2. VF01에서 "카피 컨트롤이 없습니다" 오류가 납니다.
VTFA(오더 기반) 또는 VTFL(납품 기반)에 해당 "선행 문서유형 → 청구유형" 조합이 없는 경우입니다. 커스텀 문서유형(ZCR 등)을 만들었다면 표준 CR→G2 항목을 참조해 조합을 복사 생성해야 합니다. 헤더뿐 아니라 품목 범주 레벨 설정까지 있어야 품목이 넘어옵니다.

Q3. G2를 만들었는데 채권이 오히려 늘었습니다.
VOFA에서 커스텀 유형을 만들 때 문서 범주(VBTYP)를 'M'으로 잘못 복사한 사례가 많습니다. 대변메모는 범주가 'O'여야 전기 방향이 반대로 잡힙니다. F2를 복사해 "Z대변메모"를 만드는 실수를 주의하세요.

Q4. CR을 만들었는데 청구가 안 됩니다.
CR/DR 문서유형에는 기본 청구 차단이 걸려 있는 구성이 일반적입니다. VA02에서 차단 해제(승인) 후 VF01을 실행하세요. 이는 버그가 아니라 감액 승인 통제 장치입니다.

Q5. 소액 단가 정정인데 CR/DR 중 뭘 써야 할지 매번 헷갈립니다.
과다 청구를 돌려주면 CR→G2, 과소 청구를 더 받으면 DR→L2입니다. 수량·단가를 원본 대비로 정정하는 청구서 정정 요청(RK) 방식도 있으므로, 정정의 근거 추적이 중요하면 RK 계열 검토를 권장합니다.

이어서 살펴보면 좋은 주제

이 글의 흐름을 이해했다면 다음 주제로 확장해 보세요. 반품 프로세스(RE 계열)와 G2의 회계 차이, 청구서 정정 요청(RK)의 양방향 정정 구조, VKOA 계정 결정으로 매출/매출차감 계정이 갈리는 원리, 그리고 청구 취소 문서(S1/S2)가 원본과 반제되는 방식이 자연스러운 다음 코스입니다. S/4HANA에서는 청구 문서 관리 Fiori 앱과 출력 관리(BRF+)까지 묶어 보면 실무 그림이 완성됩니다.

댓글 0

아직 댓글이 없습니다.