SAP

VTWEG 공통참조 vs 개별확장 — 뭐가 다를까 #shorts #SAP #ABAP

📖 개요 — 이 글에서 다루는 것

SAP SD에서 판매 문서를 하나 만들려면 반드시 영업영역(Sales Area)을 통과해야 합니다. 영업영역은 판매조직(VKORG), 유통경로(VTWEG), 제품군(SPART) 세 요소의 조합이며, 이 조합이 고객마스터 접근, 가격 조건, 판매전표유형 사용 범위를 실질적으로 제한합니다. 이 글은 가상의 전자부품 기업 시나리오로 영업영역이 데이터 접근을 어떻게 통제하는지 설정 단계별로 살펴봅니다.

  • VKORG / VTWEG / SPART 세 요소의 역할과 조합 원리 이해
  • 영업영역별 고객마스터(KNVV) 확장과 접근 제한 확인
  • 공통 유통경로·공통 제품군(VOR1/VOR2)으로 마스터데이터 중복 줄이기
  • 판매전표유형(OVAZ)과 가격결정절차(OVKK)를 영업영역에 묶는 방법

📚 이 글을 보기 전에

SAP GUI 기본 조작(트랜잭션 코드 실행, SE16으로 테이블 조회)과 클라이언트·회사코드 같은 엔터프라이즈 구조의 기초 용어를 알고 있으면 충분합니다. ABAP 코딩 경험은 필요하지 않으며, 예제에 포함된 SQL·ABAP 조각은 검증 용도라 읽기만 해도 따라올 수 있습니다. FI의 회사코드(BUKRS) 개념을 알면 판매조직과의 할당 관계를 이해하는 데 도움이 됩니다.

🔧 테스트 환경과 준비물

이 글은 SAP S/4HANA 2023 온프레미스(FPS 이상) 기준으로 작성했으며, 조직구조와 관련 테이블(TVKO, TVTW, TSPA, TVTA, KNVV, TVAKZ)은 ECC 6.0에서도 거의 동일하게 동작합니다. 차이점은 고객마스터 유지보수 방식으로, S/4HANA에서는 XD01 대신 BP 트랜잭션(비즈니스 파트너 + CVI 동기화)을 사용하는 것이 일반적입니다. 준비물은 다음과 같습니다.

  • 커스터마이징 권한이 있는 개발/샌드박스 클라이언트 (SPRO 접근)
  • SE16/SE16N 테이블 조회 권한
  • 회사코드 1개가 이미 정의된 상태 (예제에서는 DN10으로 가정)

프로덕션 클라이언트에서 조직구조를 직접 수정하는 것은 권장되지 않으며, 반드시 트랜스포트를 통해 이관하세요.

💡 핵심 개념 — 세 개의 축이 만드는 좌표

영업영역을 이해하는 가장 쉬운 비유는 3차원 좌표입니다. 어떤 판매 행위든 "누가 파는가(판매조직) × 어떤 통로로 파는가(유통경로) × 무엇을 파는가(제품군)"라는 세 축 위의 한 점에서 일어나며, 그 점이 곧 영업영역입니다.

  • 판매조직(Sales Organization, VKORG) — 매출 책임 단위입니다. 법적·지역적 판매 책임을 지며 회사코드에 할당되어 매출이 어느 재무 단위로 흘러갈지 결정합니다. 정의 테이블은 TVKO입니다.
  • 유통경로(Distribution Channel, VTWEG) — 상품이 고객에게 도달하는 통로입니다. 대리점, 직판, 온라인몰처럼 통로마다 가격 정책과 최소주문량이 다를 때 분리합니다. 정의 테이블은 TVTW입니다.
  • 제품군(Division, SPART) — 제품 라인 단위입니다. 사업부별 매출 분석이나 제품군별 파트너·가격 차별화가 필요할 때 나눕니다. 정의 테이블은 TSPA입니다.

중요한 점은 세 요소를 각각 정의하는 것만으로는 아무 일도 일어나지 않는다는 것입니다. OVXG에서 세 요소를 조합해 영업영역으로 등록해야 비로소 판매 문서의 입구가 열리며, 이 조합은 TVTA 테이블에 저장됩니다. 그리고 이 조합이 세 가지 관문을 통제합니다.

  1. 고객마스터 — 고객의 판매 뷰(KNVV)는 영업영역 키로 저장됩니다. 해당 영업영역에 확장되지 않은 고객으로는 주문을 만들 수 없습니다.
  2. 가격 — 대부분의 조건 테이블 키에 VKORG·VTWEG가 포함되고, 가격결정절차 자체가 영업영역 단위(OVKK)로 결정됩니다.
  3. 문서유형 — OVAZ에서 영업영역별 허용 판매전표유형을 지정하면 그 외 유형은 차단됩니다.

즉 영업영역은 단순한 분류 코드가 아니라 데이터 접근 필터입니다. 잘 설계하면 통제 장치가 되고, 과하게 쪼개면 마스터데이터 유지보수 지옥이 됩니다.

💻 실전 예제 3단계 — 가상 기업 다온전자 시나리오

가상의 전자부품 기업 다온전자를 예로 듭니다. 국내 판매조직 DN11 하나에서 스마트가전 부품(제품군 A1)과 산업용 센서(제품군 S1)를 판매하며, 유통경로는 대리점(P1)과 온라인 직판(P2) 두 가지입니다.

1단계 — 조직 단위 정의와 영업영역 조합

SPRO 경로 엔터프라이즈 구조 → 정의 → 판매/유통에서 판매조직 DN11, 유통경로 P1/P2, 제품군 A1/S1을 정의합니다. 이어서 할당 단계에서 판매조직을 회사코드 DN10에 연결(OVX3)하고, 판매조직에 유통경로(OVXK)와 제품군(OVXA)을 할당한 뒤, OVXG에서 영업영역을 조합합니다. 다온전자는 4개 조합 중 3개만 등록합니다 — 산업용 센서는 온라인 직판을 하지 않기 때문입니다.

-- SE16N에서 TVTA 조회: 등록된 영업영역 확인
SELECT vkorg, vtweg, spart
  FROM tvta
 WHERE vkorg = 'DN11';
-- 결과:
-- DN11  P1  A1   (대리점 × 가전부품)
-- DN11  P1  S1   (대리점 × 산업센서)
-- DN11  P2  A1   (직판 × 가전부품)
-- DN11/P2/S1 조합은 의도적으로 미등록 → 주문 입구 자체가 없음

이 미등록이 첫 번째 접근 제한입니다. VA01에서 DN11/P2/S1을 입력하면 문서 생성 화면에 진입조차 할 수 없습니다.

2단계 — 고객마스터 확장과 공통 조직 참조 (실무 시나리오)

대리점 고객 "미르테크"를 BP 트랜잭션으로 생성하면서 영업영역 DN11/P1/A1의 판매 뷰를 함께 만듭니다. 이때 KNVV에 해당 키의 레코드가 생성됩니다. 그런데 미르테크가 산업센서(S1)도 구매하려 하면 어떻게 될까요? VA01에서 DN11/P1/S1로 주문을 만들면 "고객이 영업영역 DN11 P1 S1에 대해 정의되지 않았습니다" 오류가 발생합니다. KNVV에 그 키의 레코드가 없기 때문입니다.

해결책은 두 가지입니다. 첫째, BP에서 영업영역별로 일일이 확장하는 방법. 둘째, 공통 제품군(VOR2)·공통 유통경로(VOR1)로 참조를 걸어 마스터데이터를 한 곳만 유지하는 방법입니다. 다온전자는 고객·가격 정책이 제품군과 무관하게 동일하므로 공통 제품군 00을 만들어 A1과 S1이 모두 00을 참조하게 합니다. 참조 관계는 TVKOS(제품군)·TVKOV(유통경로)에 저장됩니다.

" 주문 인터페이스 개발 시 자주 쓰는 사전 검증 로직 (로깅 포함)
DATA(lv_msg) = ||.
SELECT SINGLE @abap_true FROM knvv
  WHERE kunnr = @iv_kunnr
    AND vkorg = @iv_vkorg
    AND vtweg = @iv_vtweg
    AND spart = @iv_spart
  INTO @DATA(lv_exists).
IF lv_exists IS INITIAL.
  lv_msg = |고객 { iv_kunnr }: 영업영역 { iv_vkorg }/{ iv_vtweg }/{ iv_spart } 미확장|.
  " BAL 애플리케이션 로그에 기록 후 주문 생성 중단
  RAISE EXCEPTION TYPE zcx_sales_area_check
    EXPORTING textid = zcx_sales_area_check=>customer_not_extended.
ENDIF.

주의할 점: 공통 참조를 걸면 검증·조회 시 참조 대상 영업영역의 KNVV를 봐야 합니다. 위 검증 로직도 실무에서는 TVKOS/TVKOV의 참조 필드를 먼저 읽어 키를 변환한 뒤 조회하도록 확장하는 것이 일반적입니다.

3단계 — 문서유형·가격 제한과 운영 관점 (프로덕션 수준)

다온전자는 온라인 직판(P2)에서 무상 샘플 주문을 금지하려 합니다. OVAZ에서 영업영역 DN11/P2/A1에 허용 전표유형으로 표준주문(OR 계열의 자체 유형 ZDN1)만 등록하면, 무상 유형은 해당 영업영역에서 차단됩니다. 할당은 TVAKZ에 저장됩니다.

-- 영업영역별 허용 전표유형 확인
SELECT vkorg, vtweg, spart, auart
  FROM tvakz
 WHERE vkorg = 'DN11' AND vtweg = 'P2';
-- DN11  P2  A1  ZDN1  → 이 조합에서는 ZDN1만 사용 가능

가격도 같은 원리입니다. OVKK에서 "영업영역 + 전표 가격결정지시자 + 고객 가격결정지시자" 조합으로 가격결정절차를 지정하므로, 대리점(P1)에는 대리점 할인 조건이 포함된 절차를, 직판(P2)에는 정가 절차를 배정할 수 있습니다. 조건 레코드(VK11) 역시 대부분 VKORG·VTWEG를 키로 가지므로 경로별 단가가 자연스럽게 분리됩니다. 운영 관점에서 함께 챙길 사항은 다음과 같습니다.

  • 보안 — 권한 객체 V_VBAK_VKO로 사용자별 접근 가능한 판매조직·유통경로·제품군을 제한할 수 있습니다. 조직구조 설계와 권한 설계를 같은 축으로 맞추면 롤 관리가 단순해집니다.
  • 성능·유지보수 — 공통 유통경로·제품군을 쓰면 KNVV·조건 레코드 수가 조합 수만큼 늘어나는 것을 막아, 마스터데이터 정합성 문제와 조회 부하를 함께 줄입니다.
  • 테스트 — 이관 전 체크리스트로 (1) TVTA 조합 존재, (2) 대표 고객의 KNVV 확장 여부, (3) OVAZ 차단 동작(VA01 음성 테스트), (4) OVKK 절차 결정 로그(가격 분석 화면)를 확인하는 것이 일반적입니다.

⚠️ 삽질 노트

Q1. VA01에서 "고객이 해당 영업영역에 대해 생성되지 않았습니다" 오류가 납니다.
KNVV에 해당 영업영역 키의 레코드가 없는 경우입니다. BP에서 판매 뷰를 확장하거나, 정책상 동일하다면 VOR1/VOR2 공통 참조를 검토하세요. 참조 설정 후에는 참조 대상 영업영역 쪽에만 마스터를 유지해야 합니다.

Q2. OVAZ에 아무것도 등록하지 않았는데 모든 전표유형이 열립니다. 버그인가요?
아닙니다. TVAKZ에 항목이 하나도 없는 영업영역은 "제한 없음"으로 동작하는 것이 표준 로직입니다. 하나라도 등록하는 순간 화이트리스트 방식으로 전환되므로, 부분 등록 시 기존에 쓰던 유형이 갑자기 막히지 않는지 확인해야 합니다.

Q3. 새 유통경로를 추가했더니 기존 단가가 하나도 안 잡힙니다.
조건 레코드 키에 VTWEG가 포함되어 있어 신규 경로용 레코드가 없기 때문입니다. VK11로 새 경로에 레코드를 만들거나, 조건 마스터에 대한 공통 유통경로 참조(TVKOV의 조건 참조 필드)를 활용해 기존 경로 레코드를 재사용하는 방법이 있습니다.

Q4. 제품군을 너무 잘게 나눴다가 후회하는 경우가 많다던데요.
제품군은 자재마스터·고객마스터·리포팅 전반에 퍼지는 축이라 나중에 통합하기가 매우 어렵습니다. "가격·파트너·문서 흐름이 실제로 다른가?"를 기준으로 최소한만 나누고, 분석 목적의 분류는 자재그룹이나 CDS 기반 리포팅 차원으로 해결하는 편이 일반적으로 안전합니다.

🚀 더 파볼 주제

영업영역이 잡히면 그 위에 얹히는 결정 로직들을 순서대로 익히는 것을 권합니다. 판매 오피스·판매 그룹(영업영역 하위의 내부 조직), 파트너 결정(영업영역별 파트너 기능), 가격결정절차 상세(조건 기법 16개 필드), 출하 포인트 결정, 그리고 S/4HANA의 비즈니스 파트너(CVI) 구조가 자연스러운 다음 단계입니다. 특히 조건 기법은 이 글에서 본 OVKK의 원리를 출력·계정결정 등 SD 전반으로 확장한 것이라 학습 효율이 높습니다.

댓글 0

아직 댓글이 없습니다.