주문부터 현금 회수까지, 청구 및 송장 발행 데이터 템플릿
주문부터 현금 회수까지, 청구 및 송장 발행 데이터 템플릿
- 심층 분석에 권장되는 속성
- 추적할 주요 프로세스 단계와 마일스톤
- SAP ECC 데이터 추출 실무 안내
주문부터 현금 회수까지, 청구 및 송장 발행 속성
| 이름 | 설명 | ||
|---|---|---|---|
| 시작 시간 EventTime | 특정 활동이나 이벤트가 발생한 시점을 나타내는 타임스탬프입니다. | ||
| 설명 이벤트 시간은 청구서 처리 과정에서 각 활동이 발생한 정확한 날짜와 시간을 기록합니다. process mining의 시간 기반 분석에 필요한 기본 데이터로, 처리 시간 계산, 병목 식별, 서비스 수준 협약에 따른 프로세스 성과 모니터링에 사용됩니다. 일반적으로 변경 사항이나 문서 생성을 기록하는 여러 SAP 테이블의 날짜 필드(예: 전기일(BUDAT))와 시간 필드(UZEIT)를 결합해 구성합니다. 정확한 타임스탬프는 신뢰할 수 있는 이벤트 로그를 만들고 성과 분석의 타당성을 확보하는 데 중요합니다. 중요한 이유 성과 분석의 기반이 되는 속성으로, 프로세스 단계 간 처리 시간과 대기 시간을 계산할 수 있습니다. 확보 방법 BKPF(BUDAT, CPUTM), VBRK(ERDAT, ERZET), CDHDR(UDATE, UTIME)와 같은 변경 로그 테이블 등 여러 테이블의 날짜 및 시간 필드에서 구성합니다. 예시 2023-04-15T10:30:00Z2023-04-16T11:00:00Z2023-05-20T09:00:00Z | |||
| 청구서 번호 InvoiceNumber | 청구 문서를 식별하는 고유 번호로, 청구 프로세스의 기본 케이스 ID로 사용됩니다. | ||
| 설명 SAP에서 청구 문서 번호라고 부르는 청구서 번호는 각 청구서를 고유하게 식별합니다. process mining에서는 이 번호를 CaseId로 사용해 생성, 전기, 발송, 대금 수령, 반제 등 관련 활동을 하나의 종단 간 프로세스 인스턴스로 묶습니다. 청구서 번호를 기준으로 분석하면 각 청구 거래의 시작부터 최종 정산까지 전체 흐름을 확인할 수 있습니다. 이를 바탕으로 매출채권 회수 기간(DSO), 전체 청구서 처리 시간과 같은 KPI를 계산하고, 성과를 측정하고 개선할 수 있습니다. 중요한 이유 청구 거래별 전체 흐름을 추적하는 데 필요한 기준 키입니다. 이를 통해 처리 시간, 병목, 편차를 분석할 수 있습니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: VBELN 예시 90001234900012359000123690001237 | |||
| 활동 ActivityName | 청구서 처리 과정에서 발생한 업무 이벤트 또는 단계를 나타내는 이름입니다. | ||
| 설명 이 속성은 '청구서 생성', '청구서 전기', '고객 대금 수령'과 같이 청구 프로세스에서 발생한 특정 작업이나 상태 변경을 나타냅니다. 활동은 다양한 시스템 이벤트, 문서 상태 변경 또는 사용자가 실행한 특정 트랜잭션 코드에서 개념적으로 도출됩니다. 활동의 순서가 프로세스 흐름을 구성하며, 이는 process mining 분석의 기반이 됩니다. 활동을 살펴보면 실제로 어떤 단계가 어떤 순서로 얼마나 자주 수행되는지 파악하고, 설계된 프로세스와 실제 실행 방식의 차이를 확인할 수 있습니다. 중요한 이유 프로세스 맵의 단계를 정의하며, 프로세스 흐름과 편차, 병목을 시각화하고 분석할 수 있게 합니다. 확보 방법 트랜잭션 코드(CDHDR-TCODE), 문서 상태 변경(VBUK-FKSTK), 회계 문서 전기 등 여러 출처에서 도출하는 개념적 속성입니다. 예시 송장 생성송장 전기결제 안내 발송송장 반제 | |||
| 고객 번호 CustomerNumber | 청구서를 발행받는 고객을 식별하는 고유 번호입니다. | ||
| 설명 고객 번호는 청구서를 특정 고객 또는 비즈니스 파트너와 연결합니다. 고객 특성에 따라 청구 프로세스를 구분하고 분석하는 데 필요한 속성입니다. 분석가는 이 필드를 사용해 고객별 매출채권 회수 기간(DSO)을 비교하고, 지급이 자주 늦어지는 고객을 찾거나 지급 조건 준수 여부를 분석할 수 있습니다. 이러한 패턴을 파악하면 고객 관계를 관리하고 고객군별 추심 전략을 개선하는 데 도움이 됩니다. 중요한 이유 고객별 지급 행태를 파악하고 DSO를 비교하며 추심 전략을 조정할 수 있습니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: KUNRG(지급인) 또는 KUNAG(판매처). 예시 100023200541CUST-A487910345 | |||
| 사용자 이름 UserName | 활동을 수행하거나 문서를 생성한 사용자의 ID입니다. | ||
| 설명 청구서 생성이나 대금 전기와 같은 이벤트를 담당한 SAP 사용자 ID를 기록합니다. 프로세스에서 사람의 역할을 분석하는 데 필요한 속성입니다. 이 데이터를 활용하면 사용자나 팀별 성과 차이를 조사하고, 교육이 필요한 부분을 파악하며, 규정 준수 문제를 발견할 수 있습니다. 또한 사람이 직접 수행한 활동과 시스템 또는 배치 사용자가 실행한 자동화 단계를 구분하는 데도 사용되며, 이는 자동화율 계산에 중요합니다. 중요한 이유 사용자별 성과와 업무량을 분석하고 수작업과 자동화된 활동을 구분해 자동화 및 효율성 개선을 뒷받침합니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: ERNAM(생성자), BKPF, 필드: USNAM(사용자 이름), 또는 CDHDR, 필드: USERNAME(사용자). 예시 JSMITHBW_BATCHLROSSIMKUMAR | |||
| 청구 문서 유형 BillingDocumentType | 청구서, 대변 메모, 차변 메모 등 청구 문서의 유형을 구분하는 코드입니다. | ||
| 설명 청구 문서 유형은 업무 목적에 따라 거래를 여러 범주로 분류합니다. 예를 들어 'F2'는 표준 고객 청구서, 'G2'는 대변 메모를 나타냅니다. SAP에서 이 분류를 설정해 청구 문서 유형별 처리 방식을 제어합니다. process mining에서는 다양한 청구 시나리오를 필터링하고 비교하는 데 필요한 속성입니다. 분석가는 표준 청구서와 대변 메모의 프로세스를 따로 살펴보고 각 흐름과 처리 시간, 과제를 파악해 개선 방안을 구체화할 수 있습니다. 중요한 이유 표준 청구서와 대변 메모처럼 흐름이 크게 다른 청구 프로세스를 구분해 분석할 수 있습니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: FKART 예시 F2G2L2IV | |||
| 청구서 총액 TotalInvoiceAmount | 청구 문서의 총 순액입니다. | ||
| 설명 세금을 제외한 청구서의 총 순액입니다. 청구 금액은 청구 프로세스와 관련된 중요한 재무 데이터입니다. 청구서를 고액과 소액으로 나눠 처리 흐름이 다른지 분석할 수 있습니다. 추심 우선순위를 정하거나 고액 청구서의 승인 또는 지급이 늦어지는 이유를 조사하는 데도 활용할 수 있습니다. 이 재무 정보를 더하면 프로세스를 한층 구체적으로 분석할 수 있습니다. 중요한 이유 청구 금액에 따른 분석이 가능합니다. 예를 들어 고액 청구서의 처리 흐름이 다르거나 반제까지 더 오래 걸리는지 확인할 수 있습니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: NETWR 예시 1500.7525000.00500.0012345.67 | |||
| 회사 코드 CompanyCode | 청구서를 발행한 법인을 식별하는 코드입니다. | ||
| 설명 회사 코드는 SAP에서 독립적인 법률 및 회계 단위를 나타냅니다. 청구서를 포함한 모든 재무 거래는 특정 회사 코드에 전기됩니다. 회사 코드는 기본 조직 데이터 요소입니다. process mining에서는 회사 코드별로 청구 프로세스 성과를 분석하고 비교합니다. 이를 통해 한 법인의 우수 사례를 다른 법인에 적용할 수 있는지 확인하고, 회사의 조직 구조에 맞춰 분석할 수 있습니다. 중요한 이유 법인별 프로세스를 필터링하고 비교할 수 있어 재무 분석과 조직 간 성과 비교에 활용됩니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: BUKRS 예시 10002000US01DE01 | |||
| 문서 날짜 DocumentDate | 원본 문서에 기재된 날짜로, 공급업체나 작성자가 제공합니다. | ||
| 설명 문서 날짜는 원본 문서가 발행된 날짜입니다. 청구 업무에서는 일반적으로 청구서 생성일이며, 지급 기한을 계산하는 기준으로 사용됩니다. 재무 보고와 매출채권 회수 기간(DSO) 같은 주요 지표 계산에 중요합니다. 고객 관점에서 추심 기간이 시작되는 시점을 나타냅니다. 문서 날짜와 전기일의 차이를 분석하면 청구 문서 처리 과정의 내부 지연을 파악할 수 있습니다. 중요한 이유 청구서 경과 기간과 DSO를 계산하는 기준으로, 재무 및 지급 조건 분석에 필요한 참조 날짜입니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: FKDAT(청구일) 예시 2023-04-152023-04-162023-05-20 | |||
| 반제일 ClearingDate | 대금을 수령하고 매출채권에서 청구서를 반제한 날짜입니다. | ||
| 설명 반제일은 청구서와 같은 미결 항목을 재무 시스템에서 지급 완료 또는 '반제'로 표시한 날짜입니다. 이 날짜를 기준으로 대금이 수금되고 대사가 완료된 것으로 봅니다. 반제일은 주문부터 현금 수령까지의 주기에서 가장 중요한 날짜 중 하나입니다. 매출채권 회수 기간(DSO)과 청구서 발행부터 대금 수령까지의 전체 처리 시간을 계산하는 종료 시점입니다. 반제일을 분석하면 추심 프로세스의 효과를 측정할 수 있습니다. 중요한 이유 청구서 처리 과정의 마지막 단계를 나타냅니다. DSO와 전체 처리 시간을 계산하는 종료 시점이며, 대금 회수 효율을 보여줍니다. 확보 방법 SAP ECC 테이블: BSAD, 필드: AUGDT 예시 2023-05-142023-06-012023-06-25 | |||
| 소스 시스템 SourceSystem | 데이터를 추출한 소스 시스템을 식별합니다. | ||
| 설명 데이터가 생성된 기준 시스템을 나타내는 속성입니다. 여러 ERP 인스턴스나 통합 시스템을 사용하는 기업 환경에서 이 필드로 출처별 데이터를 구분할 수 있습니다. process mining에서는 데이터 검증과 시스템 또는 조직 단위 간 프로세스 비교 분석에 필요합니다. 일반적으로 데이터 추출 시 정적 값으로 입력해 데이터셋의 출처를 표시합니다. 중요한 이유 데이터의 출처를 파악할 수 있습니다. 여러 시스템을 사용하는 환경에서 데이터 무결성을 확인하고 시스템별 분석을 수행하는 데 중요합니다. 확보 방법 일반적으로 데이터 추출, 변환, 적재(ETL) 과정에서 추가하는 정적 값으로, 특정 SAP ECC 인스턴스(예: 'ECC_PROD_NA')를 식별합니다. 예시 SAP_ECC_PRODECC_EU_100SAP_US_FIN | |||
| 영업 조직 SalesOrganization | 제품이나 서비스의 판매를 담당하는 조직 단위입니다. | ||
| 설명 영업 조직은 SAP에서 상품과 서비스를 유통하고 판매 조건을 협의하는 조직 단위입니다. 영업 및 유통 운영을 구성하는 데 사용되는 주요 필드입니다. process mining에서는 영업 구조에 따라 청구 프로세스를 분석할 수 있습니다. 영업 조직별 성과를 비교해 청구 업무가 더 효율적인 지역이나 사업 부문을 찾고, 우수 사례를 표준화하는 데 활용할 수 있습니다. 중요한 이유 영업 부문이나 지역별 성과를 비교해 우수 사례와 개선이 필요한 영역을 파악할 수 있습니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: VKORG 예시 1000NA01EU01AP01 | |||
| 자동화 여부 IsAutomated | 시스템 사용자 또는 자동화 기능이 활동을 수행했는지 나타내는 플래그입니다. | ||
| 설명 수작업과 자동화된 활동을 구분하는 계산 속성으로, 참 또는 거짓 값을 갖습니다. 일반적으로 사용자 이름이 'BATCHUSER' 또는 'SAPSYSTEM'과 같은 시스템 또는 배치 사용자 ID 목록에 포함되는지 확인해 값을 도출합니다. 이 플래그는 청구 프로세스의 자동화 수준을 측정하는 데 필요합니다. 효율성을 높이고 비용을 줄이려는 조직에서 자동화 수준은 주요 목표 중 하나입니다. 자동 청구율 KPI를 이 속성으로 계산해 자동화 추진 현황을 추적할 수 있습니다. 중요한 이유 자동 청구율 계산에 직접 활용해 프로세스 효율성을 측정하고 자동화 프로젝트의 영향을 추적할 수 있습니다. 확보 방법 사용자 이름 속성에서 도출합니다. 예를 들어 IF UserName IN ('BATCH', 'SYSTEM', 'RFCUSER') THEN true ELSE false와 같은 로직을 적용할 수 있습니다. 예시 truefalse | |||
| 재작업 여부 IsRework | 활동이 재작업 또는 수정 단계인지 나타내는 플래그입니다. | ||
| 설명 '청구서 수정'이나 문서 취소 전기처럼 재작업에 해당하는 활동을 식별하는 계산 속성입니다. 일반적으로 활동명이나 청구 문서 취소에 사용하는 'VF11'과 같은 트랜잭션 코드를 바탕으로 참 또는 거짓 값을 도출합니다. process mining에서는 이 플래그로 청구 프로세스의 재작업 규모를 정량화할 수 있습니다. 청구서 수정률과 같은 KPI 계산에 직접 활용하고, 프로세스 맵에서 재작업 루프를 시각화해 운영 비용을 높이고 지급을 지연시키는 비효율과 품질 문제를 파악할 수 있습니다. 중요한 이유 오류 수정에 투입되는 작업량을 보여줘 프로세스 비효율과 품질 문제를 정량화하고 재작업 KPI를 산출하는 데 도움이 됩니다. 확보 방법 활동명 또는 트랜잭션 코드에서 도출합니다. 예를 들어 IF ActivityName = 'Invoice Corrected' OR TransactionCode = 'VF11' THEN true ELSE false를 적용할 수 있습니다. 예시 truefalse | |||
| 전기일 PostingDate | 문서를 재무 회계 장부에 전기한 날짜입니다. | ||
| 설명 전기일은 거래가 총계정원장에 기록되는 회계 기간을 결정합니다. 회계 및 재무 보고에 중요한 날짜입니다. 문서 생성일과 전기일 사이의 지연은 청구 문서의 내부 처리 비효율을 나타낼 수 있습니다. process mining에서 전기일은 청구서 처리 과정의 주요 시점을 나타냅니다. 청구서 생성부터 전기까지 걸린 시간은 청구 부서의 업무 효율을 측정하는 KPI로 활용할 수 있습니다. 중요한 이유 재무 처리의 주요 시점을 나타내며 회계에 중요합니다. 청구서 생성부터 전기까지 걸린 시간은 내부 처리 효율을 측정하는 지표입니다. 확보 방법 SAP ECC 테이블: BKPF, 필드: BUDAT 예시 2023-04-152023-04-172023-05-21 | |||
| 지급 조건 PaymentTerms | 지급 일정 등 판매자가 거래를 완료하기 위해 적용하는 조건입니다. | ||
| 설명 지급 조건은 '30일 이내 지급' 또는 '60일 이내 지급'처럼 대금 지급 시점을 정합니다. 고객과 합의하는 조건으로, 현금 흐름에 영향을 미치는 주요 요소입니다. 지급 조건별로 프로세스를 분석하면 특정 조건이 긴 지급 주기나 높은 연체율과 관련 있는지 확인할 수 있습니다. 이를 바탕으로 고객과 더 나은 조건을 협의하거나 재무 계획을 조정할 수 있습니다. 청구서 지급 기한을 계산할 때도 사용합니다. 중요한 이유 합의된 지급 조건에 따른 고객의 지급 행태와 현금 흐름 영향을 분석해 거래 조건을 개선하는 데 필요한 정보를 제공합니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: ZTERM 예시 Z030Z060Z001 | |||
| 청구서 지급 기한 InvoiceDueDate | 고객이 대금을 지급해야 하는 날짜입니다. | ||
| 설명 청구서 지급 기한은 지급 조건에 명시된 대금 지급 마감일입니다. 매출채권 관리와 추심 활동 시작 시점을 정하는 데 필요합니다. 실제 지급일과 비교해 정시 지급률 KPI를 계산하는 데 사용합니다. 지급 기한별로 청구서를 분석하면 현금 흐름을 예측하고, 지급 예정이거나 연체된 건의 추심 우선순위를 정할 수 있습니다. 일반적으로 기준일과 지급 조건을 바탕으로 계산합니다. 중요한 이유 정시 지급 성과를 측정하는 기준으로, 매출채권 관리와 현금 흐름 예측에 필요합니다. 확보 방법 기준일(BSEG-ZFBDT)과 지급 조건(BSEG-ZTERM)을 바탕으로 계산합니다. 항상 직접 대응하는 필드에 저장되는 것은 아닙니다. 예시 2023-05-152023-05-302023-06-20 | |||
| 최근 데이터 업데이트 LastDataUpdate | 소스 시스템에서 데이터를 마지막으로 새로 고치거나 추출한 시점입니다. | ||
| 설명 소스 시스템의 데이터가 마지막으로 업데이트된 시점을 나타냅니다. 분석 중인 데이터의 최신성을 파악하는 데 필요한 정보를 제공합니다. 대시보드와 보고서에서 이 타임스탬프를 통해 데이터의 최신성을 확인하고, 최근 거래가 반영되는 시점에 대한 기대치를 조정할 수 있습니다. 일반적으로 데이터 추출이 끝날 때 생성됩니다. 중요한 이유 데이터가 얼마나 최신인지 알려주므로, 분석 결과를 바탕으로 운영 의사결정을 내릴 때 중요합니다. 확보 방법 데이터 추출, 변환, 적재(ETL) 과정에서 생성하고 저장합니다. 예시 2023-10-27T02:00:00Z2023-10-28T02:00:00Z | |||
| 통화 Currency | 청구서 금액에 적용되는 통화 코드입니다. | ||
| 설명 USD, EUR, JPY 등 거래 통화를 나타냅니다. 청구서 총액과 같은 금액을 올바르게 해석하는 데 필요한 정보입니다. 다국적 기업의 데이터를 분석할 때 통화 필드는 재무 수치를 정확하게 해석하고 환산하는 데 필요합니다. 일관된 보고를 지원하며, 적절한 통화 환산 없이 금액을 합산해 재무 분석이 왜곡되는 일을 방지합니다. 중요한 이유 모든 금액을 올바르게 해석하는 데 필요한 정보로, 여러 통화를 사용하는 환경에서 정확한 재무 분석을 지원합니다. 확보 방법 SAP ECC 테이블: VBRK, 필드: WAERK 예시 USDEURGBPJPY | |||
| 트랜잭션 코드 TransactionCode | 활동을 수행하는 데 사용한 SAP 트랜잭션 코드입니다. | ||
| 설명 트랜잭션 코드(T-Code)는 SAP의 특정 기능이나 프로그램을 식별하는 고유 코드입니다. 예를 들어 'VF01'은 청구 문서를 생성하는 코드입니다. 각 이벤트의 T-Code를 기록하면 프로세스가 시스템에서 어떤 방식으로 실행됐는지 기술적으로 확인할 수 있습니다. 이 정보는 근본 원인 분석에 유용합니다. 예를 들어 오류가 자주 발생한다면 표준이 아닌 트랜잭션 코드를 사용했는지 확인할 수 있습니다. 활동명을 도출하고 프로세스에서 사용한 시스템 기능을 파악하는 데도 도움이 됩니다. 중요한 이유 활동이 수행된 방식을 기술적으로 파악할 수 있어, 프로세스 편차의 근본 원인을 분석하고 표준에서 벗어난 사용자 작업을 식별하는 데 도움이 됩니다. 확보 방법 SAP ECC 테이블: CDHDR, 필드: TCODE 예시 VF01VF02FB01F-28 | |||
| 판매 문서 번호 SalesDocumentNumber | 청구서 발행의 계기가 된 원본 판매 오더의 식별자입니다. | ||
| 설명 청구서를 거래를 시작한 판매 오더와 직접 연결하는 속성입니다. 주문부터 대금 수령까지의 종단 간 프로세스를 분석하려면 이 추적 정보가 필요합니다. 청구 프로세스와 선행 판매 오더 프로세스를 연결하면 고객 주문부터 대금 수령까지 전체 처리 시간을 분석할 수 있습니다. 청구 지연의 원인이 영업, 이행 또는 청구 부서 중 어디에 있는지 파악해 프로세스 전체를 살펴볼 수 있습니다. 중요한 이유 청구 프로세스를 판매 오더와 연결해 주문부터 대금 수령까지 종단 간으로 분석하고, 부서 간 지연을 파악할 수 있습니다. 확보 방법 SAP ECC 테이블: VBRP, 필드: VGBEL 예시 100000451000004610000047 | |||
주문부터 현금 회수까지, 청구 및 송장 발행 활동
| 활동 | 설명 | ||
|---|---|---|---|
| 고객 결제 수령 | 고객 대금을 수령해 현금 입금이나 은행 입금으로 시스템에 전기한 상태입니다. 별도의 결제 문서가 생성되며, 이 단계에서는 아직 특정 송장에 반영되지 않습니다. | ||
| 중요한 이유 현금 전환 주기의 주요 시점입니다. 송장 발송부터 대금 수령까지 걸리는 시간은 매출채권 회전일수(DSO)를 구성하는 주요 요소입니다. 확보 방법 일반적으로 고객 결제를 나타내는 문서 유형(예: 'DZ')으로 BKPF와 BSEG에 새 문서가 기록됩니다. 전기일(BUDAT)이 이벤트 시점입니다. 기록 BKPF에 기록된 고객 결제 문서의 전기일을 기준으로 합니다. 이벤트 유형 explicit | |||
| 고객에게 송장 발송 | 인쇄, 이메일, EDI와 같은 지정된 출력 채널을 통해 송장이 고객에게 발송된 것을 나타냅니다. 일반적으로 출력 관리 시스템 로그에서 확인합니다. | ||
| 중요한 이유 고객의 결제 기한을 계산하기 시작하는 중요한 시점입니다. 이 단계가 지연되면 예상 결제일이 늦어지고 대금 회수 효율에도 영향을 줍니다. 확보 방법 송장에 해당하는 출력 유형의 메시지 상태 테이블(NAST)에 기록된 처리 날짜와 시간으로 추정할 수 있습니다. 기록 처리 상태가 '1'(정상 처리)인 NAST 테이블 항목을 바탕으로 추정합니다. 이벤트 유형 inferred | |||
| 송장 반제 | 결제가 완료된 송장의 최종 상태입니다. 해당 미결 항목이 결제나 대변 메모로 마감되어 송장 대금이 모두 정산된 상태를 나타냅니다. | ||
| 중요한 이유 송장에 대한 Order to Cash 주기가 성공적으로 완료된 시점입니다. 전체 평균 송장 처리 시간을 측정하는 주요 종료 이벤트입니다. 확보 방법 BSEG 테이블의 송장 항목에 반제 문서(AUGBL)와 반제일(AUGDT) 필드가 입력되면 발생합니다. 기록 BSEG 테이블의 송장 항목에 기록된 반제일(AUGDT)에 이벤트가 발생합니다. 이벤트 유형 explicit | |||
| 송장 생성 | 시스템에서 청구 문서가 생성된 시점을 나타냅니다. 송장에 해당하는 특정 문서 유형으로 회계 문서 헤더 테이블(BKPF)에 새 항목이 생성되면 이 이벤트를 기록합니다. | ||
| 중요한 이유 송장 발행 프로세스의 시작점입니다. 이 이벤트부터 걸린 시간을 분석하면 송장 생성 주기를 측정할 수 있으며, 매출채권 회전일수(DSO) 계산의 기준이 됩니다. 확보 방법 BKPF 테이블에 기록됩니다. 특정 문서 번호(BELNR)의 생성 날짜(CPUDT)와 시간(CPUTM)이 이 이벤트를 나타냅니다. 문서 유형(BLART)으로 송장 여부를 확인합니다. 기록 송장 문서의 BKPF 테이블 생성 타임스탬프(CPUDT)를 기준으로 합니다. 이벤트 유형 explicit | |||
| 송장 전기 | 송장이 매출채권 보조원장과 총계정원장에 정식으로 기록됩니다. 이 이벤트로 송장이 법적 효력을 갖고 고객의 채무로 반영됩니다. | ||
| 중요한 이유 대금 회수 기간을 공식적으로 계산하기 시작하는 중요한 시점입니다. 송장 생성부터 전기까지 걸리는 시간을 보면 현금 흐름에 영향을 주는 내부 처리 지연을 파악할 수 있습니다. 확보 방법 BKPF 테이블에 기록됩니다. 문서 번호(BELNR)의 전기일(BUDAT)이 이 이벤트를 나타냅니다. 임시 저장 문서는 이 시점에 전기 문서로 전환됩니다. 기록 송장 문서의 BKPF 테이블 전기일(BUDAT)을 기준으로 합니다. 이벤트 유형 explicit | |||
| 결제 안내 발송 | 시스템이 연체 송장에 대해 독촉장이나 결제 안내를 생성해 고객에게 발송한 상태입니다. 독촉 이력 로그에서 확인합니다. | ||
| 중요한 이유 대금 회수 전략의 효과를 평가하는 데 도움이 됩니다. 안내 발송부터 결제까지 걸린 시간을 분석하는 것은 결제 안내 효과 KPI를 측정하는 데 중요합니다. 확보 방법 독촉 실행으로 생성되는 독촉 데이터 테이블, 특히 MHNK(독촉 데이터 헤더)와 MHND(독촉 데이터 항목)에 기록됩니다(트랜잭션 F150). 기록 연체 항목에 대해 독촉 실행(F150)을 수행할 때 기록됩니다. 이벤트 유형 explicit | |||
| 분쟁 사례 생성 | 일반적으로 고객 불만으로 인해 송장에 대한 공식 분쟁이 등록된 상태입니다. SAP Dispute Management 시스템에 기록됩니다. | ||
| 중요한 이유 결제 지연 위험이 있는 송장을 찾아 고객 불만의 원인이 되는 문제를 보여 줍니다. 중요한 예외 처리 프로세스가 시작되는 시점입니다. 확보 방법 송장의 회계 문서와 연결된 분쟁 사례 테이블(UDM_CASE)에 사례가 생성되면 기록됩니다. 기록 사용자가 UDM_DISPUTE 트랜잭션으로 분쟁 사례를 생성할 때 기록됩니다. 이벤트 유형 explicit | |||
| 송장 결제 기한 도래 | 결제 조건에 따라 송장 대금의 공식 결제 기한이 도래한 날을 나타내는 계산 이벤트입니다. 사용자나 시스템이 수행하는 활동은 아니지만 중요한 시점입니다. | ||
| 중요한 이유 결제 행태와 규정 준수 분석에 필요합니다. 기한 내 결제와 연체 결제를 구분하고 기한 내 결제율 KPI를 계산하는 기준입니다. 확보 방법 현재 날짜와 순 결제 기한을 비교해 산출합니다. 결제 기한은 BSEG-ZFBDT 필드에서 확인하거나 기준일과 결제 조건을 바탕으로 계산합니다. 기록 시스템 날짜와 송장 항목(BSEG)의 순 결제 기한 필드를 비교합니다. 이벤트 유형 calculated | |||
| 송장 대손 처리 | 송장 대금을 회수할 수 없다고 판단해 미수 금액을 대손 계정으로 처리하는 대체 최종 상태입니다. 고객 결제 없이 송장을 마감합니다. | ||
| 중요한 이유 부정적인 프로세스 결과이자 매출 손실을 나타냅니다. 이 이벤트를 추적하면 대손 원인을 분석하고 신용 관리 정책을 개선할 수 있습니다. 확보 방법 청구서 반제 트랜잭션을 분석해 추론합니다. 반제 문서가 특정 대손 비용 G/L 계정에 전기되면 해당 청구서는 대손상각 처리된 것으로 간주합니다. 기록 반제 트랜잭션에서 지정된 대손 G/L 계정으로 전기된 내역이 확인되면 추론합니다. 이벤트 유형 inferred | |||
| 송장 수정 | 처음 발행한 송장에 오류가 있어 취소한 후 다시 처리하는 재작업 활동입니다. 원 송장과 연결된 취소 문서를 찾아 기록합니다. | ||
| 중요한 이유 프로세스 비효율과 품질 문제를 보여 줍니다. 수정이 자주 발생하면 상위 영업 데이터나 청구 데이터에 문제가 있다는 신호이며, 송장 재작업 및 오류율 대시보드 분석에 활용할 수 있습니다. 확보 방법 BKPF-STBLG가 원 문서를 가리키는 취소 문서를 찾아 확인합니다. 해당 취소 문서가 생성된 시점이 이벤트입니다. 기록 취소 문서가 생성될 때 기록됩니다(예: FB08 사용). 이벤트 유형 explicit | |||
| 송장 승인 | 송장을 전기하거나 고객에게 발송할 수 있도록 정식으로 승인된 상태입니다. 임시 저장 문서가 전기 문서로 전환된 시점을 승인으로 추정하는 경우가 많습니다. | ||
| 중요한 이유 병목이 자주 발생하는 내부 승인 워크플로를 추적합니다. 이 활동을 분석하면 승인이 지연되는 담당자를 찾아 송장 승인 흐름 분석 대시보드를 지원할 수 있습니다. 확보 방법 VBKPF의 임시 저장 상태에서 BKPF의 전기 상태로 문서가 전환된 것을 바탕으로 추정할 수 있습니다. 워크플로 시스템을 사용하는 경우 워크플로 로그에 명시적인 이벤트가 기록될 수도 있습니다. 기록 임시 저장 문서(VBKPF)의 생성일과 최종 문서(BKPF)의 전기일을 비교합니다. 이벤트 유형 inferred | |||
| 송장 임시 저장 | 송장 문서를 총계정원장에 전기하지 않고 임시 상태로 저장한 것입니다. 정보가 불완전하거나 최종 전기 전에 검토가 필요한 경우에 주로 사용합니다. | ||
| 중요한 이유 전기 전 단계와 잠재적인 지연을 추적합니다. 임시 저장 상태가 오래 지속되면 데이터 품질 문제나 사전 승인 과정의 병목을 나타낼 수 있습니다. 확보 방법 임시 저장 문서는 VBKPF 테이블에 저장됩니다. 여기에 문서가 생성된 후 나중에 전기되면 이 활동으로 기록합니다. 기록 FV70과 같은 트랜잭션을 사용해 임시 저장 문서를 저장할 때 기록됩니다. 이벤트 유형 explicit | |||
| 송장에 결제 반영 | 수령한 고객 결제를 특정 미결 송장에 대사해 반영하고 해당 항목을 반제 대상으로 표시한 상태입니다. 결제와 채무를 연결하는 대사 단계입니다. | ||
| 중요한 이유 현금 반영 주기를 측정하는 데 중요한 활동입니다. 입금 반영이 늦어지면 실제 매출채권 상태가 정확히 나타나지 않고 사용 가능한 현금이 파악되지 않을 수 있습니다. 확보 방법 예를 들어 F-32와 같은 반제 트랜잭션으로 추정할 수 있습니다. 이 트랜잭션은 송장 항목의 반제 필드를 채우며, 이벤트 타임스탬프는 반제일입니다. 기록 송장 항목 테이블(BSEG)에 반제일(AUGDT)이 입력된 것을 바탕으로 추정합니다. 이벤트 유형 inferred | |||
데이터 추출 가이드
단계
- ABAP 편집기 열기: SAP ECC 시스템에 로그인합니다. 트랜잭션 코드
SE38을 사용해 ABAP 편집기로 이동합니다. - 프로그램 생성: Program 필드에 새 프로그램 이름을 입력합니다. 예를 들어
Z_PM_O2C_INVOICE_EXTRACT를 입력한 뒤 Create 버튼을 클릭합니다. 설명이 포함된 제목을 입력하고 프로그램 유형을 'Executable Program'으로 설정합니다. - 선택 화면 정의: 프로그램 소스 코드에서 선택 화면 매개변수를 정의합니다. 이를 통해 사용자가 추출할 데이터를 필터링할 수 있습니다. 주요 매개변수에는 문서 생성일 범위(
S_ERDAT), 회사 코드(S_BUKRS), 청구 문서 유형(S_VBTYP)이 포함됩니다. - 데이터 구조 정의: 최종 이벤트 로그 데이터를 담을 내부 테이블 구조를 선언합니다. 이 구조에는
InvoiceNumber,ActivityName,EventTime과UserName,BillingDocumentType,CustomerNumber,CompanyCode,TotalInvoiceAmount등의 권장 속성이 포함되어야 합니다. - 데이터 선택 로직 구현: 데이터를 선택하는 핵심 ABAP 로직을 작성합니다. 먼저 선택 화면의 입력값을 기준으로
VBRK및BKPF테이블에서 주요 청구 문서를 선택해 임시 내부 테이블에 저장합니다. - 활동 추출: 처음 추출한 청구 문서 목록을 순회합니다. 각 문서에 대해 여러 테이블을 추가로 조회해 필요한 13개 활동을 식별합니다. 예를 들어
NAST테이블에서 '고객에게 송장 발송' 이벤트를,BSEG에서 반제 정보('송장 반제', '지급 적용')를,MHNK에서 독촉 데이터('지급 안내 발송')를 조회합니다. - 이벤트 로그 테이블 구성: 앞 단계에서 찾은 각 활동에 대해 최종 이벤트 로그 내부 테이블에 새 레코드를 추가합니다.
InvoiceNumber,ActivityName,EventTime및 기타 속성이 원본 테이블의 올바른 필드에 매핑되었는지 확인합니다. - 애플리케이션 서버에 기록: 반복 처리가 끝나 최종 이벤트 로그 테이블이 채워지면
OPEN DATASET,LOOP AT... TRANSFER,CLOSE DATASET문을 사용해 내부 테이블의 내용을 SAP 애플리케이션 서버에 일반 파일로 기록합니다. 접근 가능한 논리 파일 경로를 지정합니다. - 파일 가져오기: 트랜잭션 코드
AL11을 사용해 애플리케이션 서버 디렉터리로 이동한 후 생성된 파일을 찾습니다. SAP Basis 팀과 협의해 파일을 서버에서 로컬 컴퓨터나 공유 네트워크 위치로 다운로드합니다. - 최종 형식 확인: 다운로드한 파일을 열어 헤더 행이 있는 쉼표로 구분된 값(CSV) 파일인지 확인합니다. ProcessMind에 업로드할 수 있도록 UTF-8 인코딩으로 저장합니다.
구성
- 사전 요건: ABAP 프로그램을 생성하고 실행할 권한(트랜잭션 SE38)이 필요합니다.
VBRK,VBRP,BKPF,BSEG,NAST,MHNK,UDM_CASE_ATTR00(분쟁 관리용) 등 FI 및 SD 테이블을 읽을 권한도 필요합니다. - 기간 선택: 프로그램에는 일반적으로 문서 생성일(
VBRK/BKPF의ERDAT)을 기준으로 하는 필수 날짜 범위 매개변수가 있어야 합니다. 초기 추출에서는 데이터 규모를 관리하기 쉽도록 3~6개월 범위를 권장합니다. - 주요 필터: 추출 범위를 제한하려면 항상
CompanyCode(BUKRS)로 필터링합니다. 관련 송장 유형만 포함하도록 청구 문서 유형(VBRK의VBTYP) 또는 회계 문서 유형(BKPF의BLART)으로 필터링하는 것도 권장합니다. 예를 들어 표준 회계 송장에는 'RV'를 사용하고 대변 메모 등은 제외합니다. - 성능 고려 사항: 몇 개월을 초과하는 대규모 데이터 추출은 세션 시간 초과를 방지하기 위해 백그라운드 작업으로 실행해야 합니다. ABAP 로직은 인덱스 테이블 읽기를 활용하도록 최적화하고, 데이터베이스를 조회하는 중첩 반복문은 피해야 합니다. 데이터를 먼저 내부 테이블로 선택한 뒤 처리하는 방식을 권장합니다.
- 출력 파일 설정: ABAP 코드에서 애플리케이션 서버의 출력 파일 경로와 CSV 구분자를 지정해야 합니다. 구분자는 일반적으로 쉼표나 세미콜론을 사용합니다. 경로가 전역으로 설정되어 있고 접근 가능한 디렉터리인지 확인합니다.
샘플 쿼리 abap
REPORT Z_PM_O2C_INVOICE_EXTRACT.
*&---------------------------------------------------------------------*
*& Tables
*&---------------------------------------------------------------------*
TABLES: VBRK, BKPF.
*&---------------------------------------------------------------------*
*& Type Definitions for Event Log Output
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
invoicenumber TYPE vbrk-vbeln,
activityname TYPE string,
eventtime TYPE timestamp,
username TYPE xubname,
billingdocumenttype TYPE vbrk-vbtyp,
customernumber TYPE vbrk-kunnr,
companycode TYPE vbrk-bukrs,
totalinvoiceamount TYPE vbrk-netwr,
END OF ty_event_log.
*&---------------------------------------------------------------------*
*& Data Declarations
*&---------------------------------------------------------------------*
DATA: gt_event_log TYPE TABLE OF ty_event_log,
gs_event_log TYPE ty_event_log.
DATA: BEGIN OF gs_invoice,
vbeln TYPE vbrk-vbeln, " SD Doc (Invoice)
awkey TYPE bkpf-awkey, " Accounting Doc Reference Key
bukrs TYPE vbrk-bukrs, " Company Code
kunnr TYPE vbrk-kunnr, " Customer
vbtyp TYPE vbrk-vbtyp, " SD Doc Type
netwr TYPE vbrk-netwr, " Net Value
waerk TYPE vbrk-waerk, " Currency
fkdat TYPE vbrk-fkdat, " Billing Date
erdat TYPE vbrk-erdat, " Creation Date
erzet TYPE vbrk-erzet, " Creation Time
ernam TYPE vbrk-ernam, " Creator
belnr TYPE bkpf-belnr, " Acct Doc
gjahr TYPE bkpf-gjahr, " Fiscal Year
cpudt TYPE bkpf-cpudt, " Acct Doc Entry Date
cputm TYPE bkpf-cputm, " Acct Doc Entry Time
usnam TYPE bkpf-usnam, " Acct Doc User
stblg TYPE bkpf-stblg, " Reversal Doc
END OF gs_invoice.
DATA: gt_invoices LIKE TABLE OF gs_invoice.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_erdat FOR vbrk-erdat OBLIGATORY,
s_bukrs FOR vbrk-bukrs OBLIGATORY,
s_vbtyp FOR vbrk-vbtyp.
PARAMETERS: p_path TYPE string DEFAULT '/usr/sap/trans/tmp/invoice_extract.csv' OBLIGATORY.
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
" 1. Select base set of invoices
SELECT vbrk~vbeln, vbrk~bukrs, vbrk~kunnr, vbrk~vbtyp, vbrk~netwr, vbrk~waerk,
vbrk~fkdat, vbrk~erdat, vbrk~erzet, vbrk~ernam,
bkpf~belnr, bkpf~gjahr, bkpf~cpudt, bkpf~cputm, bkpf~usnam, bkpf~stblg, bkpf~awkey
INTO CORRESPONDING FIELDS OF TABLE gt_invoices
FROM vbrk
INNER JOIN bkpf ON bkpf~awkey = vbrk~vbeln AND bkpf~awtyp = 'VBRK'
WHERE vbrk~erdat IN s_erdat
AND vbrk~bukrs IN s_bukrs
AND vbrk~vbtyp IN s_vbtyp.
IF gt_invoices IS INITIAL.
MESSAGE 'No invoices found for the selected criteria.' TYPE 'I'.
RETURN.
ENDIF.
LOOP AT gt_invoices INTO gs_invoice.
CLEAR gs_event_log.
gs_event_log-invoicenumber = gs_invoice-vbeln.
gs_event_log-billingdocumenttype = gs_invoice-vbtyp.
gs_event_log-customernumber = gs_invoice-kunnr.
gs_event_log-companycode = gs_invoice-bukrs.
gs_event_log-totalinvoiceamount = gs_invoice-netwr.
" Activity: Invoice Generated (using accounting doc creation)
gs_event_log-activityname = 'Invoice Generated'.
gs_event_log-username = gs_invoice-usnam.
CONCATENATE gs_invoice-cpudt gs_invoice-cputm INTO DATA(lv_ts_gen).
CONVERT DATE gs_invoice-cpudt TIME gs_invoice-cputm INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
" Activity: Invoice Posted (same as generated for non-parked docs)
gs_event_log-activityname = 'Invoice Posted'.
gs_event_log-username = gs_invoice-usnam.
CONVERT DATE gs_invoice-cpudt TIME gs_invoice-cputm INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
" Activity: Invoice Approved (inferred by posting)
gs_event_log-activityname = 'Invoice Approved'.
APPEND gs_event_log TO gt_event_log.
" Activity: Invoice Sent To Customer
SELECT SINGLE addat, aduhr FROM nast
INTO (DATA(lv_nast_date), DATA(lv_nast_time))
WHERE kappl = 'V3' AND objky = gs_invoice-vbeln AND vszst > '0'.
IF sy-subrc = 0.
gs_event_log-activityname = 'Invoice Sent To Customer'.
gs_event_log-username = sy-uname.
CONVERT DATE lv_nast_date TIME lv_nast_time INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
ENDIF.
" Activity: Invoice Corrected / Reversed
IF gs_invoice-stblg IS NOT INITIAL.
SELECT SINGLE cpudt, cputm, usnam FROM bkpf
INTO (DATA(lv_rev_date), DATA(lv_rev_time), DATA(lv_rev_user))
WHERE belnr = gs_invoice-stblg AND gjahr = gs_invoice-gjahr.
IF sy-subrc = 0.
gs_event_log-activityname = 'Invoice Corrected'.
gs_event_log-username = lv_rev_user.
CONVERT DATE lv_rev_date TIME lv_rev_time INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
" Activity: Payment Applied, Cleared, Due Date, Written Off (from BSEG)
SELECT SINGLE augdt, augbl, zfBDT, hkont FROM bseg
INTO (DATA(lv_augdt), DATA(lv_augbl), DATA(lv_zfbdt), DATA(lv_hkont))
WHERE bukrs = gs_invoice-bukrs
AND belnr = gs_invoice-belnr
AND gjahr = gs_invoice-gjahr
AND koart = 'D'. " Customer line
IF sy-subrc = 0.
" Due Date Reached (Calculated event)
IF lv_zfbdt IS NOT INITIAL.
gs_event_log-activityname = 'Invoice Due Date Reached'.
gs_event_log-username = 'System'.
CONVERT DATE lv_zfbdt INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
ENDIF.
" Cleared, Applied, Write-Off
IF lv_augdt IS NOT INITIAL.
SELECT SINGLE usnam, cpudt, cputm, blart FROM bkpf
INTO (DATA(lv_clear_user), DATA(lv_clear_date), DATA(lv_clear_time), DATA(lv_clear_type))
WHERE belnr = lv_augbl AND bukrs = gs_invoice-bukrs.
IF sy-subrc = 0.
gs_event_log-username = lv_clear_user.
CONVERT DATE lv_clear_date TIME lv_clear_time INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
IF lv_clear_type = 'DZ'. " Standard Customer Payment
gs_event_log-activityname = 'Customer Payment Received'. APPEND gs_event_log TO gt_event_log.
gs_event_log-activityname = 'Payment Applied To Invoice'. APPEND gs_event_log TO gt_event_log.
gs_event_log-activityname = 'Invoice Cleared'. APPEND gs_event_log TO gt_event_log.
ELSE. " Assuming other clearing doc types could be write-offs
gs_event_log-activityname = 'Invoice Written Off'.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
" Activity: Payment Reminder Issued (Dunning)
SELECT COUNT(*) FROM mhnk WHERE kunnr = gs_invoice-kunnr AND bukrs = gs_invoice-bukrs AND lafdn > gs_invoice-cpudt.
IF sy-subrc = 0 AND sy-dbcnt > 0.
SELECT SINGLE lafdn FROM mhnk
INTO DATA(lv_dunning_date)
WHERE kunnr = gs_invoice-kunnr AND bukrs = gs_invoice-bukrs AND lafdn > gs_invoice-cpudt.
gs_event_log-activityname = 'Payment Reminder Issued'.
gs_event_log-username = 'System'.
CONVERT DATE lv_dunning_date INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
ENDIF.
" Activity: Invoice Parked (Example from VBKPF, may require system specific logic)
SELECT SINGLE cpudt, cputm, usnam FROM vbkpf
INTO (DATA(lv_park_date), DATA(lv_park_time), DATA(lv_park_user))
WHERE awkey = gs_invoice-vbeln AND awsys = 'LOG' AND bstat = 'V'.
IF sy-subrc = 0.
gs_event_log-activityname = 'Invoice Parked'.
gs_event_log-username = lv_park_user.
CONVERT DATE lv_park_date TIME lv_park_time INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
ENDIF.
" Activity: Dispute Case Created (Requires Dispute Management module)
SELECT SINGLE create_date, create_time, create_user FROM udm_case_attr00
INTO (DATA(lv_disp_date), DATA(lv_disp_time), DATA(lv_disp_user))
WHERE [Your logic to link invoice to dispute case, e.g., via a custom field or object link].
IF sy-subrc = 0.
gs_event_log-activityname = 'Dispute Case Created'.
gs_event_log-username = lv_disp_user.
CONVERT DATE lv_disp_date TIME lv_disp_time INTO TIME STAMP gs_event_log-eventtime TIME ZONE sy-zonlo.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
*&---------------------------------------------------------------------*
*& Write data to file
*&---------------------------------------------------------------------*
OPEN DATASET p_path FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
MESSAGE 'Error opening file.' TYPE 'E'.
ENDIF.
" Header
DATA(lv_header) = 'InvoiceNumber,ActivityName,EventTime,UserName,BillingDocumentType,CustomerNumber,CompanyCode,TotalInvoiceAmount'.
TRANSFER lv_header TO p_path.
LOOP AT gt_event_log INTO gs_event_log.
DATA(lv_line) = |
{ gs_event_log-invoicenumber }|
,{ gs_event_log-activityname }|
,{ gs_event_log-eventtime }|
,{ gs_event_log-username }|
,{ gs_event_log-billingdocumenttype }|
,{ gs_event_log-customernumber }|
,{ gs_event_log-companycode }|
,{ gs_event_log-totalinvoiceamount }|.
TRANSFER lv_line TO p_path.
ENDLOOP.
CLOSE DATASET p_path.
WRITE: 'Extraction complete. File created at:', p_path. 단계
- 사전 요건 및 접근 권한: 쿼리에 지정된
VBRK,BKPF,BSAD,NAST,CDHDR,CDPOS,SCASE등의 SAP ECC 테이블을 읽기 전용으로 조회할 수 있는 데이터베이스 사용자가 있는지 확인합니다. 일반적으로 시스템 관리자나 특정 데이터 분석 팀에만 이 수준의 접근 권한이 부여됩니다. - 데이터베이스 연결: DBeaver, Oracle SQL Developer, Microsoft SQL Server Management Studio 등의 표준 SQL 클라이언트 도구를 사용해 SAP ECC 데이터베이스에 연결합니다.
- SQL 쿼리 준비: 'query' 섹션에 제공된 전체 SQL 쿼리를 복사해 SQL 클라이언트 편집기에 붙여 넣습니다.
- 자리표시자 수정: 쿼리의 자리표시자를 사용 환경에 맞는 값으로 바꿉니다. 다음 항목을 포함합니다.
'YYYYMMDD': 분석 기간의 시작일과 종료일로 모든 항목을 바꿉니다. 데이터 규모를 관리할 수 있도록 기간을 제한해야 합니다.'XXXX': 분석할 회사 코드로 바꿉니다.[Your Invoice Output Type]: 고객에게 송장을 발송하는 데 사용하는 출력 유형 코드를 지정합니다. 예: 'RD00'.[Your Bad Debt G/L Account]: 회수 불능 송장을 상각하는 데 사용하는 총계정원장 계정 번호를 입력합니다.[Your Dispute Case Invoice Attribute]: 분쟁 관리 설정에서 송장 번호를 저장하는 데 사용하는 속성 이름을 지정합니다. 예: 'INVOICE_ID'.
- 타임스탬프 함수 검토: 쿼리는 일반적인
CAST(CONCAT(date_field, time_field) AS TIMESTAMP)구문을 사용합니다. 데이터베이스에 따라 구문을 조정해야 할 수 있습니다. 예를 들어 Oracle에서는TO_TIMESTAMP, SQL Server에서는DATETIMEFROMPARTS를 사용할 수 있습니다. - 쿼리 실행: 수정한 쿼리를 실행합니다. SAP 테이블의 크기와 선택한 날짜 범위에 따라 실행에 상당한 시간이 걸릴 수 있습니다.
- 결과 확인: 쿼리 실행이 끝나면 결과에
InvoiceNumber,ActivityName,EventTime및 권장 속성이 포함되어 있는지 확인합니다. 오류가 있거나 결과가 비어 있지 않은지도 살펴봅니다. - CSV로 내보내기: SQL 클라이언트에서 전체 결과를 CSV 파일로 내보냅니다. 특수 문자 문제를 방지하려면 UTF-8 인코딩을 사용합니다.
- 업로드 준비: process mining 도구에 업로드하기 전에 CSV 열 이름이 필수 속성 이름과 정확히 일치하는지 확인합니다. 예:
InvoiceNumber,ActivityName,EventTime,UserName.
구성
- 데이터베이스 연결: 기본 SAP ECC 데이터베이스에 대한 직접적인 읽기 전용 SQL 연결이 필요합니다. 이 방식은 SAP 애플리케이션 계층을 완전히 거치지 않습니다.
- 권한: 데이터베이스 사용자는 쿼리에서 사용하는 모든 테이블에
SELECT권한이 있어야 합니다. 해당 테이블은 FI, SD 및 경우에 따라 FSCM 모듈에 걸쳐 있습니다. - 기간: 성능과 데이터 규모를 적정 수준으로 유지하려면 쿼리에서 특정 기간을 반드시 지정해야 합니다. 처음에는 3~6개월 범위를 권장합니다. 쿼리의 여러 부분에 있는 날짜 필터 자리표시자
'YYYYMMDD'를 설정해야 합니다. - 회사 코드 필터: 쿼리는 회사 코드(
BUKRS)로 필터링하도록 구성되어 있습니다. 일반적으로 한 번에 하나 또는 소수의 회사 코드를 분석합니다. - 문서 유형 설정: 송장 수정, 대손 상각, 문서 발송 등의 이벤트를 식별하는 로직은 표준 SAP 설정에 따라 달라집니다. 조직에서 사용자 정의 문서 유형(
BLART), 출력 유형(KSCHL) 또는 총계정원장 계정을 사용하는 경우 쿼리를 조정해야 할 수 있습니다. - 성능 고려 사항: 운영 중인 SAP 시스템에서 이 쿼리를 실행하면 리소스를 많이 사용해 운영 성능에 영향을 줄 수 있습니다. 대규모 추출은 사용량이 적은 시간대에 실행하거나 전용 보고용 데이터베이스 복제본을 사용하는 것이 좋습니다.
샘플 쿼리 sql
WITH InvoiceBase AS (
SELECT
VBRK.VBELN AS InvoiceNumber,
VBRK.FKART AS BillingDocumentType,
VBRK.KUNRG AS CustomerNumber,
VBRK.BUKRS AS CompanyCode,
VBRK.NETWR AS TotalInvoiceAmount,
VBRK.ERNAM AS CreatorName,
VBRK.ERDAT AS CreationDate,
VBRK.ERZET AS CreationTime
FROM VBRK
WHERE VBRK.ERDAT BETWEEN '20230101' AND '20231231' -- Filter by Invoice Creation Date
AND VBRK.BUKRS IN ('1000') -- Filter by Company Code
AND VBRK.FKART NOT IN ('S1', 'S2') -- Exclude cancelled invoices
)
-- 1. Invoice Generated
SELECT
ib.InvoiceNumber,
'Invoice Generated' AS ActivityName,
CAST(CONCAT(ib.CreationDate, ib.CreationTime) AS TIMESTAMP) AS EventTime,
ib.CreatorName AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
ib.CompanyCode,
ib.TotalInvoiceAmount
FROM InvoiceBase ib
UNION ALL
-- 2. Invoice Parked
SELECT
SUBSTRING(b.AWKEY, 1, 10) AS InvoiceNumber,
'Invoice Parked' AS ActivityName,
CAST(CONCAT(b.CPUDT, b.CPUTM) AS TIMESTAMP) AS EventTime,
b.USNAM AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
b.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM BKPF b
JOIN InvoiceBase ib ON SUBSTRING(b.AWKEY, 1, 10) = ib.InvoiceNumber
WHERE b.AWTYP = 'VBRK' AND b.BSTAT = 'V' AND b.CPUDT BETWEEN '20230101' AND '20231231'
UNION ALL
-- 3. Invoice Posted
SELECT
SUBSTRING(b.AWKEY, 1, 10) AS InvoiceNumber,
'Invoice Posted' AS ActivityName,
CAST(CONCAT(b.CPUDT, b.CPUTM) AS TIMESTAMP) AS EventTime,
b.USNAM AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
b.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM BKPF b
JOIN InvoiceBase ib ON SUBSTRING(b.AWKEY, 1, 10) = ib.InvoiceNumber
WHERE b.AWTYP = 'VBRK' AND b.BSTAT = '' AND b.CPUDT BETWEEN '20230101' AND '20231231'
UNION ALL
-- 4. Invoice Approved (from Parked to Posted)
SELECT
SUBSTRING(h.OBJECTID, 4, 10) AS InvoiceNumber,
'Invoice Approved' as ActivityName,
CAST(CONCAT(h.UDATE, h.UTIME) AS TIMESTAMP) AS EventTime,
h.USERNAME AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
ib.CompanyCode,
ib.TotalInvoiceAmount
FROM CDHDR h
JOIN CDPOS p ON h.MANDANT = p.MANDANT AND h.OBJECTCLAS = p.OBJECTCLAS AND h.OBJECTID = p.OBJECTID AND h.CHANGENR = p.CHANGENR
JOIN InvoiceBase ib ON SUBSTRING(h.OBJECTID, 4, 10) = ib.InvoiceNumber
WHERE h.OBJECTCLAS = 'BELEGV'
AND p.TABNAME = 'BKPF'
AND p.FNAME = 'BSTAT'
AND p.VALUE_OLD = 'V'
AND p.VALUE_NEW = ' '
AND h.UDATE BETWEEN '20230101' AND '20231231'
UNION ALL
-- 5. Invoice Sent To Customer
SELECT
n.OBJKY AS InvoiceNumber,
'Invoice Sent To Customer' AS ActivityName,
CAST(CONCAT(n.DATVR, n.UHRVR) AS TIMESTAMP) AS EventTime,
n.VSTAT AS UserName, -- User who processed is not directly available, using processing status as a proxy
ib.BillingDocumentType,
ib.CustomerNumber,
ib.CompanyCode,
ib.TotalInvoiceAmount
FROM NAST n
JOIN InvoiceBase ib ON n.OBJKY = ib.InvoiceNumber
WHERE n.KSCHL = '[Your Invoice Output Type]' -- E.g., 'RD00'
AND n.VSTAT = '1' -- Processed successfully
AND n.DATVR BETWEEN '20230101' AND '20231231'
UNION ALL
-- 6. Invoice Corrected (Reversed)
SELECT
SUBSTRING(orig_doc.AWKEY, 1, 10) AS InvoiceNumber,
'Invoice Corrected' AS ActivityName,
CAST(CONCAT(rev_doc.CPUDT, rev_doc.CPUTM) AS TIMESTAMP) AS EventTime,
rev_doc.USNAM AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
rev_doc.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM BKPF orig_doc
JOIN BKPF rev_doc ON orig_doc.STBLG = rev_doc.BELNR AND orig_doc.BUKRS = rev_doc.BUKRS AND orig_doc.GJAHR = rev_doc.STJAH
JOIN InvoiceBase ib ON SUBSTRING(orig_doc.AWKEY, 1, 10) = ib.InvoiceNumber
WHERE orig_doc.AWTYP = 'VBRK' AND orig_doc.STBLG IS NOT NULL AND rev_doc.CPUDT BETWEEN '20230101' AND '20231231'
UNION ALL
-- 7. Invoice Due Date Reached
SELECT
SUBSTRING(b.AWKEY, 1, 10) AS InvoiceNumber,
'Invoice Due Date Reached' AS ActivityName,
CAST(CONCAT(bs.ZFBDT, '000000') AS TIMESTAMP) AS EventTime,
'System' AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
b.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM BSEG bs
JOIN BKPF b ON bs.MANDT = b.MANDT AND bs.BUKRS = b.BUKRS AND bs.BELNR = b.BELNR AND bs.GJAHR = b.GJAHR
JOIN InvoiceBase ib ON SUBSTRING(b.AWKEY, 1, 10) = ib.InvoiceNumber
WHERE b.AWTYP = 'VBRK' AND bs.KOART = 'D' AND bs.ZFBDT BETWEEN '20230101' AND '20231231'
UNION ALL
-- 8. Payment Reminder Issued
SELECT
SUBSTRING(b.AWKEY, 1, 10) AS InvoiceNumber,
'Payment Reminder Issued' AS ActivityName,
CAST(CONCAT(h.LAUFD, '000000') AS TIMESTAMP) AS EventTime,
h.LAUFI AS UserName, -- Dunning Run ID
ib.BillingDocumentType,
ib.CustomerNumber,
d.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM MHND d
JOIN MHNK h ON d.MANDT = h.MANDT AND d.LAUFD = h.LAUFD AND d.LAUFI = h.LAUFI
JOIN BKPF b ON d.MANDT = b.MANDT AND d.BUKRS = b.BUKRS AND d.BELNR = b.BELNR AND d.GJAHR = b.GJAHR
JOIN InvoiceBase ib ON SUBSTRING(b.AWKEY, 1, 10) = ib.InvoiceNumber
WHERE h.LAUFD BETWEEN '20230101' AND '20231231'
UNION ALL
-- 9. Dispute Case Created
SELECT
attr.ATTR_VALUE AS InvoiceNumber,
'Dispute Case Created' AS ActivityName,
sc.CREATE_TIME AS EventTime,
sc.CREATED_BY AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
ib.CompanyCode,
ib.TotalInvoiceAmount
FROM SCMG_T_CASE_ATTR attr
JOIN SCASE sc ON attr.CASE_GUID = sc.CASE_GUID
JOIN InvoiceBase ib ON attr.ATTR_VALUE = ib.InvoiceNumber
WHERE attr.ATTR_NAME = '[Your Dispute Case Invoice Attribute]' -- e.g., 'INVOICE_ID'
AND CAST(sc.CREATE_TIME AS DATE) BETWEEN '20230101' AND '20231231'
UNION ALL
-- 10, 11, 12. Clearing Events (Payment, Clearing, Write-Off)
SELECT
InvoiceNumber,
ActivityName,
EventTime,
UserName,
BillingDocumentType,
CustomerNumber,
CompanyCode,
TotalInvoiceAmount
FROM (
SELECT
bsad.XBLNR AS InvoiceNumber,
CASE
WHEN clearing_item.HKONT = '[Your Bad Debt G/L Account]' THEN 'Invoice Written Off'
ELSE 'Customer Payment Received'
END AS ActivityName,
CAST(CONCAT(clearing_doc.CPUDT, clearing_doc.CPUTM) AS TIMESTAMP) AS EventTime,
clearing_doc.USNAM AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
bsad.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM BSAD bsad
JOIN InvoiceBase ib ON bsad.XBLNR = ib.InvoiceNumber
JOIN BKPF clearing_doc ON bsad.MANDT = clearing_doc.MANDT AND bsad.BUKRS = clearing_doc.BUKRS AND bsad.AUGBL = clearing_doc.BELNR AND bsad.AUGGJ = clearing_doc.GJAHR
LEFT JOIN BSEG clearing_item ON clearing_doc.MANDT = clearing_item.MANDT AND clearing_doc.BUKRS = clearing_item.BUKRS AND clearing_doc.BELNR = clearing_item.BELNR AND clearing_doc.GJAHR = clearing_item.GJAHR AND clearing_item.HKONT = '[Your Bad Debt G/L Account]' -- e.g. '148000'
WHERE bsad.AUGDT BETWEEN '20230101' AND '20231231' AND bsad.UMSKZ = ''
UNION ALL
SELECT
bsad.XBLNR AS InvoiceNumber,
'Payment Applied To Invoice' AS ActivityName,
CAST(CONCAT(bsad.AUGDT, '000000') AS TIMESTAMP) AS EventTime,
clearing_doc.USNAM AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
bsad.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM BSAD bsad
JOIN InvoiceBase ib ON bsad.XBLNR = ib.InvoiceNumber
JOIN BKPF clearing_doc ON bsad.MANDT = clearing_doc.MANDT AND bsad.BUKRS = clearing_doc.BUKRS AND bsad.AUGBL = clearing_doc.BELNR AND bsad.AUGGJ = clearing_doc.GJAHR
WHERE bsad.AUGDT BETWEEN '20230101' AND '20231231' AND bsad.UMSKZ = ''
UNION ALL
SELECT
bsad.XBLNR AS InvoiceNumber,
'Invoice Cleared' AS ActivityName,
CAST(CONCAT(bsad.AUGDT, '235959') AS TIMESTAMP) AS EventTime, -- Add time to separate from 'Payment Applied'
clearing_doc.USNAM AS UserName,
ib.BillingDocumentType,
ib.CustomerNumber,
bsad.BUKRS AS CompanyCode,
ib.TotalInvoiceAmount
FROM BSAD bsad
JOIN InvoiceBase ib ON bsad.XBLNR = ib.InvoiceNumber
JOIN BKPF clearing_doc ON bsad.MANDT = clearing_doc.MANDT AND bsad.BUKRS = clearing_doc.BUKRS AND bsad.AUGBL = clearing_doc.BELNR AND bsad.AUGGJ = clearing_doc.GJAHR
WHERE bsad.AUGDT BETWEEN '20230101' AND '20231231' AND bsad.UMSKZ = ''
) AS ClearingEvents 단계
- 사전 요건: SAP 인증 커넥터가 포함된 라이선스 보유 ETL 도구가 있는지 확인합니다. 예: SAP Connector가 포함된 Informatica PowerCenter 또는 SAP Connector가 포함된 Talend. BKPF, BSEG, VBRK, NAST, MHNK, UDM_CASE_ATTR00, CDHDR, CDPOS 등 필요한 재무, 영업 및 시스템 테이블을 읽을 수 있는 SAP 사용자 자격 증명과 권한도 확인합니다.
- SAP 연결 설정: ETL 도구에서 SAP ECC 시스템에 대한 새 연결을 만듭니다. 애플리케이션 서버, 시스템 번호, 클라이언트, 사용자, 비밀번호 등 연결 정보를 설정합니다. 연결을 테스트해 정상적으로 연결되는지 확인합니다.
- 데이터 소스 정의: 추출할 각 활동에 해당하는 SAP 테이블을 ETL 작업의 데이터 소스로 지정합니다. 예를 들어 송장 생성에는 VBRK, 전기 이벤트에는 BKPF, 고객 안내에는 NAST를 추가합니다.
- 활동별 추출 로직 구성: 필요한 13개 활동마다 별도의 데이터 흐름이나 변환을 만듭니다. 각 흐름에 관련 레코드를 선택하는 필터를 적용합니다. 예를 들어 회사 코드(BUKRS), 문서 유형(BLART), 특정 날짜 범위(예: 생성일 ERDAT)로 필터링합니다.
- 필드 매핑 및 데이터 변환: 각 데이터 흐름에서 SAP 원본 테이블 필드를 대상 이벤트 로그 구조인
InvoiceNumber,ActivityName,EventTime,UserName및 기타 권장 속성에 매핑합니다. 변환 로직을 사용해 각 흐름의ActivityName을 지정하고 날짜와 타임스탬프 형식을 올바르게 맞춥니다. - 복합 활동 처리: '송장 만기일 도래'와 같이 계산이 필요한 이벤트는 기준 지급일(ZFBDT)과 지급 조건 로직을 사용해 만기일을 계산하거나, BSEG에서 순 만기일(NETDT)을 가져옵니다. '송장 승인'처럼 변경 로그에서 도출하는 이벤트는 문서 번호와 날짜를 기준으로 BKPF와 CDHDR/CDPOS 등의 테이블을 조인해야 할 수 있습니다.
- 활동 데이터 통합: ETL 도구의 'Union' 또는 'Merge' 변환을 사용해 13개 개별 데이터 흐름의 결과를 하나의 데이터 세트로 합칩니다. 통합 전에 모든 흐름의 열 이름과 데이터 유형이 일치하는지 확인합니다.
- 대상 위치 설정: 이벤트 로그의 최종 출력 위치를 지정합니다. 일반 파일(CSV), 데이터베이스 테이블 또는 스테이징 영역에 대한 직접 연결을 사용할 수 있습니다.
- 추출 일정 설정: 추출 기간 매개변수를 설정합니다. 최초 적재에서는 6~12개월의 데이터를 추출할 수 있습니다. 이후 증분 적재에서는 마지막 실행일 이후의 데이터를 추출하도록 작업을 설정합니다.
- 실행 및 내보내기: ETL 작업을 실행합니다. 완료되면 출력 파일이 필수 형식에 맞는지 확인합니다. 최종 결과는 각 행이 하나의 고유 이벤트를 나타내며 ProcessMind에 업로드할 수 있는 단일 CSV 파일이어야 합니다.
구성
- SAP 연결: 대상 SAP ECC 시스템에 대한 애플리케이션 서버 연결이 필요합니다. SAP 사용자에게는 RFC 접근 권한과 VBRK, BKPF, BSEG, NAST 및 쿼리에 지정된 기타 테이블에 대한 권한이 필요합니다.
- ETL 도구 라이선스: 상용 ETL 도구와 해당 SAP 커넥터의 유효한 라이선스가 필요합니다.
- 기간: 시스템 부하를 과도하게 높이지 않으면서 분석에 적합한 표본을 확보하려면 3~6개월의 데이터를 추출하는 것이 좋습니다. 시작일과 종료일은 설정 가능한 매개변수로 지정합니다.
- 주요 필터: 추출 범위를 제한하려면 항상 회사 코드(BUKRS)로 필터링합니다. 표준 송장만 포함하고 대변 메모나 내부 문서 등의 다른 문서 유형은 제외하도록 관련 청구 문서 유형(VBRK-FKART)과 회계 문서 유형(BKPF-BLART)도 반드시 필터링합니다.
- 성능: BSEG와 같은 대형 테이블에서 데이터를 추출하면 시간이 오래 걸릴 수 있습니다. 선택성이 높은 필터를 사용하고 불필요한 필드 추출을 피하며, SAP 원본 시스템의 성능 영향을 줄이도록 사용량이 적은 시간대에 추출을 예약합니다.
샘플 쿼리 config
// ETL Data Extraction Logic for SAP Order-to-Cash Invoicing
// This represents the configuration logic within a graphical ETL tool.
// == Global Parameters ==
// $StartDate: '[Start Date]' (e.g., '2023-01-01')
// $EndDate: '[End Date]' (e.g., '2023-06-30')
// $CompanyCodes: '[Company Code(s)]' (e.g., '1000', '2000')
// $BillingDocTypes: '[Billing Document Type(s)]' (e.g., 'F1', 'F2')
// == Source 1: Invoice Generated ==
// Tables: VBRK
DATA_SOURCE generated_invoices FROM VBRK WHERE
ERDAT >= $StartDate AND ERDAT <= $EndDate
AND BUKRS IN ($CompanyCodes)
AND FKART IN ($BillingDocTypes)
MAP {
InvoiceNumber: VBELN,
ActivityName: 'Invoice Generated',
EventTime: ERDAT + ERZET, // Combine date and time
UserName: ERNAM,
BillingDocumentType: FKART,
CustomerNumber: KUNAG,
CompanyCode: BUKRS,
TotalInvoiceAmount: NETWR
}
// == Source 2: Invoice Posted ==
// Tables: BKPF joined with VBRK
DATA_SOURCE posted_invoices FROM BKPF as A
INNER JOIN VBRK as B ON (A.AWKEY = B.VBELN AND A.AWTYP = 'VBRK')
WHERE A.BUDAT >= $StartDate AND A.BUDAT <= $EndDate
AND A.BUKRS IN ($CompanyCodes)
AND A.BSTAT = ' '
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Invoice Posted',
EventTime: A.BUDAT + A.CPUTM, // Posting date and entry time
UserName: A.USNAM,
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Source 3: Invoice Parked ==
// Tables: BKPF joined with VBRK
DATA_SOURCE parked_invoices FROM BKPF as A
INNER JOIN VBRK as B ON (A.AWKEY = B.VBELN AND A.AWTYP = 'VBRK')
WHERE A.CPUDT >= $StartDate AND A.CPUDT <= $EndDate
AND A.BUKRS IN ($CompanyCodes)
AND A.BSTAT = 'V'
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Invoice Parked',
EventTime: A.CPUDT + A.CPUTM,
UserName: A.USNAM,
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Source 4: Invoice Approved (Transition from Parked to Posted) ==
// Tables: BKPF joined with VBRK
DATA_SOURCE approved_invoices FROM BKPF as A
INNER JOIN VBRK as B ON (A.AWKEY = B.VBELN AND A.AWTYP = 'VBRK')
WHERE A.BUDAT >= $StartDate AND A.BUDAT <= $EndDate
AND A.BUKRS IN ($CompanyCodes)
AND A.BSTAT = ' '
AND EXISTS (SELECT 1 FROM VBELEGV C WHERE C.BELNR = A.BELNR) // Check if it was ever parked
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Invoice Approved',
EventTime: A.BUDAT + A.CPUTM, // Use posting date as approval date
UserName: A.USNAM,
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Source 5: Invoice Sent To Customer ==
// Tables: NAST joined with VBRK
DATA_SOURCE sent_invoices FROM NAST as A
INNER JOIN VBRK as B ON (A.OBJKY = B.VBELN)
WHERE A.ERDAT >= $StartDate AND A.ERDAT <= $EndDate
AND B.BUKRS IN ($CompanyCodes)
AND A.VSTAT = '1' // Successfully processed
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Invoice Sent To Customer',
EventTime: A.ERDAT + A.ERUHR,
UserName: A.USNAM,
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: B.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Source 6: Invoice Corrected (Reversed) ==
// Tables: VBRK (for the reversal document)
DATA_SOURCE corrected_invoices FROM VBRK as A
WHERE A.ERDAT >= $StartDate AND A.ERDAT <= $EndDate
AND A.BUKRS IN ($CompanyCodes)
AND A.SFAKN <> '' // SFAKN is the original cancelled invoice
MAP {
InvoiceNumber: A.SFAKN, // Case ID is the original invoice
ActivityName: 'Invoice Corrected',
EventTime: A.ERDAT + A.ERZET,
UserName: A.ERNAM,
BillingDocumentType: A.FKART,
CustomerNumber: A.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: NULL // Amount belongs to the reversal doc, not original
}
// == Source 7: Invoice Due Date Reached ==
// Tables: BSEG joined with VBRK
DATA_SOURCE due_invoices FROM BSEG as A
INNER JOIN BKPF as H ON (A.BUKRS = H.BUKRS AND A.BELNR = H.BELNR AND A.GJAHR = H.GJAHR)
INNER JOIN VBRK as B ON (H.AWKEY = B.VBELN AND H.AWTYP = 'VBRK')
WHERE A.NETDT >= $StartDate AND A.NETDT <= $EndDate
AND A.BUKRS IN ($CompanyCodes)
AND A.KOART = 'D' // Customer line item
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Invoice Due Date Reached',
EventTime: A.NETDT, // Net due date
UserName: 'System',
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Source 8: Payment Reminder Issued ==
// Tables: MHNK, MHND, VBRK
DATA_SOURCE reminders FROM MHNK as A
INNER JOIN MHND as D ON (A.LAUFD = D.LAUFD AND A.LAUFI = D.LAUFI)
INNER JOIN VBRK as B ON (SUBSTRING(D.XBLNR, 1, 10) = B.VBELN) // XBLNR may need parsing
WHERE A.LAUFD >= $StartDate AND A.LAUFD <= $EndDate
AND D.BUKRS IN ($CompanyCodes)
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Payment Reminder Issued',
EventTime: A.LAUFD, // Dunning date
UserName: A.IDAPS,
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: D.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Source 9: Dispute Case Created ==
// Tables: UDM_CASE_ATTR00
DATA_SOURCE disputes FROM UDM_CASE_ATTR00 as A
WHERE A.CREATE_TIMESTAMP >= $StartDate // Timestamp format may vary
AND A.FIN_COMP_CODE IN ($CompanyCodes)
AND A.PROCESS = 'FIN_FSCM_DIS'
MAP {
InvoiceNumber: A.BILL_DOC_ID,
ActivityName: 'Dispute Case Created',
EventTime: A.CREATE_TIMESTAMP,
UserName: A.CREATE_USER,
BillingDocumentType: NULL,
CustomerNumber: A.BP_NUMBER,
CompanyCode: A.FIN_COMP_CODE,
TotalInvoiceAmount: A.DISPUTED_AMOUNT
}
// == Source 10: Customer Payment Received ==
// Tables: BKPF
DATA_SOURCE payments FROM BKPF
WHERE BUDAT >= $StartDate AND BUDAT <= $EndDate
AND BUKRS IN ($CompanyCodes)
AND BLART = 'DZ' // Example for Customer Payment
MAP {
InvoiceNumber: NULL, // Invoice not yet known
ActivityName: 'Customer Payment Received',
EventTime: BUDAT + CPUTM,
UserName: USNAM,
BillingDocumentType: NULL,
CustomerNumber: NULL, // Requires join to BSEG to get customer
CompanyCode: BUKRS,
TotalInvoiceAmount: NULL
}
// == Source 11 & 12: Payment Applied To Invoice & Invoice Cleared ==
// Tables: BSEG joined with VBRK
DATA_SOURCE cleared_items FROM BSEG as A
INNER JOIN BKPF as H ON (A.BUKRS = H.BUKRS AND A.BELNR = H.BELNR AND A.GJAHR = H.GJAHR)
INNER JOIN VBRK as B ON (H.AWKEY = B.VBELN AND H.AWTYP = 'VBRK')
WHERE A.AUGDT >= $StartDate AND A.AUGDT <= $EndDate
AND A.BUKRS IN ($CompanyCodes)
AND A.AUGBL <> ''
// Generate two records from this source
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Payment Applied To Invoice',
EventTime: A.AUGDT, // Clearing Date
UserName: H.USNAM, // User from header of original invoice doc
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: B.NETWR
}
UNION WITH {
InvoiceNumber: B.VBELN,
ActivityName: 'Invoice Cleared',
EventTime: A.AUGDT, // Clearing Date
UserName: H.USNAM,
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Source 13: Invoice Written Off ==
// Tables: BSEG (for the invoice line) and BKPF (for clearing doc type)
DATA_SOURCE written_off FROM BSEG as A
INNER JOIN BKPF as H ON (A.BUKRS = H.BUKRS AND A.BELNR = H.BELNR AND A.GJAHR = H.GJAHR)
INNER JOIN VBRK as B ON (H.AWKEY = B.VBELN AND H.AWTYP = 'VBRK')
INNER JOIN BKPF as C ON (A.AUGBL = C.BELNR AND A.BUKRS = C.BUKRS AND A.AUGGJ = C.GJAHR)
WHERE A.AUGDT >= $StartDate AND A.AUGDT <= $EndDate
AND A.BUKRS IN ($CompanyCodes)
AND C.BLART = '[Your Write-Off Document Type]' // e.g., 'AB'
MAP {
InvoiceNumber: B.VBELN,
ActivityName: 'Invoice Written Off',
EventTime: A.AUGDT,
UserName: C.USNAM, // User who posted the write-off
BillingDocumentType: B.FKART,
CustomerNumber: B.KUNAG,
CompanyCode: A.BUKRS,
TotalInvoiceAmount: B.NETWR
}
// == Final Union of all sources ==
OUTPUT generated_invoices
UNION ALL posted_invoices
UNION ALL parked_invoices
UNION ALL approved_invoices
UNION ALL sent_invoices
UNION ALL corrected_invoices
UNION ALL due_invoices
UNION ALL reminders
UNION ALL disputes
UNION ALL payments
UNION ALL cleared_items
UNION ALL written_off 시작할 준비가 되셨나요?
이 템플릿으로 데이터 준비를 간소화하고 청구 및 송장 발행 프로세스에 관한 유용한 정보를 확인하세요. 현금 흐름을 개선하기 위한 분석을 시작해 보세요.
현금 흐름을 앞당기세요. 지금 청구 및 송장 발행 프로세스를 개선하세요.
비효율을 줄이고 처리 시간을 30% 단축해 현금 흐름을 개선하세요.
신용카드 없이 이용할 수 있습니다. 몇 분 안에 개선 작업을 시작하세요.