買掛金の請求書処理向けデータテンプレート
買掛金の請求書処理向けデータテンプレート
- 詳細な分析に推奨される属性
- 追跡すべき主要なプロセスアクティビティ
- データ抽出の手順
買掛金の請求書処理に関する属性
| 名前 | 説明 | ||
|---|---|---|---|
| アクティビティ ActivityName | 請求書処理の過程で発生した、特定の業務イベントまたは手順の名称です。 | ||
| 説明 アクティビティは、買掛金プロセスにおける個別の段階や処理を表します。たとえば、「請求書を受領」「請求書を転記」「支払いを実行」などです。プロセスマップを構成する基本要素です。 アクティビティの分析は、プロセスマイニングの中核です。プロセスの流れを可視化し、よくある経路を特定し、標準プロセスからの逸脱を検出できます。また、各手順の発生頻度や所要時間も測定できます。請求書ごとのアクティビティの順序が、その請求書の処理経路を形作ります。 重要な理由 プロセスの手順を定義し、流れの可視化と分析、ボトルネックの特定、手戻りの検出を可能にします。 入手先 伝票ステータスの変更(例:BKPF-BSTAT)、変更伝票(CDHDR/CDPOSテーブル)、ワークフローログなど、さまざまな情報源から導出します。通常、個別の抽出ロジックが必要です。 例 請求書を受領請求書を承認支払いを実行請求書の支払いをブロック | |||
| イベント時刻 EventTime | アクティビティが発生した正確な日時です。 | ||
| 説明 イベント時刻は各アクティビティに関連付けられたタイムスタンプで、請求書に関するイベントの時系列を示します。プロセスの流れを把握し、時間に基づく分析を行うために欠かせないデータです。 分析では、アクティビティを正しい順序に並べ、手順間のサイクルタイムを算出し、待ち時間を特定します。また、月ごとの比較など、期間別のプロセスパフォーマンス分析にも使用します。所要時間に基づくすべての重要業績評価指標(KPI)の基礎となります。 重要な理由 イベントを時系列に並べ、サイクルタイムや所要時間などの時間に基づく指標を算出するために欠かせません。これらはプロセスマイニングの基本となります。 入手先 SAPの各種テーブルにある日付・時刻フィールドから取得します。例:作成日(BKPF-CPUDT)、転記日(BKPF-BUDAT)、消込日(BSAK-AUGDT)、変更ログのタイムスタンプ(CDHDR-UDATE/UTIME)。 例 2023-10-01T09:00:00Z2023-10-05T14:30:15Z2023-10-15T11:21:05Z | |||
| 請求書 Invoice | 請求書文書を一意に識別する番号で、買掛金プロセスの主要なケースIDとして使用されます。 | ||
| 説明 請求書は、受領から支払いまでの関連アクティビティを結び付ける中心的な対象です。SAP S/4HANAでは通常、会社コード(BUKRS)、一意の伝票番号(BELNR)、会計年度(GJAHR)を組み合わせた複合キーで識別します。 請求書単位で分析すると、請求書のライフサイクルを最初から最後まで把握できます。総サイクルタイムの算出、個々の請求書におけるボトルネックの特定、プロセス内で請求書がたどる経路の把握に欠かせません。 重要な理由 請求書ごとの処理経路を一意に識別できるため、ライフサイクル全体を追跡し、ケースごとにプロセスのパフォーマンスを分析できます。 入手先 テーブルBKPF(会計伝票ヘッダー)またはRBKP(伝票ヘッダー:請求書受領)のBUKRS、BELNR、GJAHRフィールドから導出する複合キーです。 例 1000-1900000001-20231710-1900000002-20232000-5100000003-2024 | |||
| ソースシステム SourceSystem | データの抽出元となるシステムです。 | ||
| 説明 この属性は、プロセスデータの取得元を示します。このビューでは通常、「SAP S/4HANA」が設定されます。 複数のERPや連携システムを使用する環境では、データの来歴管理と分離に欠かせないフィールドです。正しいデータセットを分析対象にできるほか、データ品質の問題をソースまでたどって原因を調べる際にも役立ちます。 重要な理由 データの取得元を示します。データガバナンス、トラブルシューティング、複数システムを利用する環境で重要です。 入手先 通常、データ抽出時にデータセットの取得元を示す固定値を追加します。 例 SAP S/4HANASAP ECC 6.0S4H_PROD_100 | |||
| 最終データ更新日時 LastDataUpdate | このレコードのデータがソースシステムから最後に更新された日時を示すタイムスタンプです。 | ||
| 説明 この属性は、SAP S/4HANAからデータを最後に抽出または更新した日時を示します。分析対象データの鮮度を把握するうえで重要なメタデータです。 プロセス分析データがどの程度最新かを確認できます。データ反映の遅れに関する見通しを立てるほか、データ更新のスケジュール設定や整合性の維持にも役立ちます。 重要な理由 データの鮮度を示し、プロセス分析がどの程度最新かを把握できます。 入手先 ソースシステムからデータを抽出する際に、この値を生成して各レコードに記録します。 例 2024-05-20T04:00:00Z2024-05-21T04:00:00Z | |||
| ユーザー名 UserName | アクティビティを実行した担当者のユーザーIDです。 | ||
| 説明 この属性には、請求書の転記、承認、消込など、特定のアクティビティを実行したSAPユーザーIDが記録されます。プロセスの手順と個々のユーザーを関連付けます。 ユーザー名で分析すると、業務負荷の分布や高い成果を上げている担当者を把握でき、追加のトレーニングが必要なユーザーも特定できます。また、ダッシュボードで承認のボトルネックを分析する際にも役立ち、遅延の原因となっている承認者を特定できます。 重要な理由 アクティビティを担当者に関連付け、ユーザーのパフォーマンスや業務負荷、職務分掌ポリシーへの準拠状況を分析できます。 入手先 通常、BKPF-USNAM(入力者)などのヘッダーテーブルや、CDHDR-USERNAME(変更者)などの変更伝票テーブルにあります。 例 ABROWNJSMITHAP_AUTOMATION | |||
| 仕入先名 VendorName | 請求書を提出した仕入先の名称です。 | ||
| 説明 この属性には、仕入先の正式名称が含まれます。請求書文書に記録された仕入先番号を通じて関連付けられています。 仕入先分析は、仕入先との関係を管理し、特定の仕入先に関するプロセス上の問題を把握するうえで重要です。「不一致のある請求書を最も多く提出している仕入先はどこか」「特定の戦略的な仕入先への支払いを常に期限内に行えているか」といった問いに答えるのに役立ちます。請求書番号や金額とともに、二重支払いの可能性を検出するための重要なフィールドでもあります。 重要な理由 仕入先別にプロセスのパフォーマンスを分析し、問題のある仕入先を特定するとともに、戦略的な仕入先との関係を適切に管理できます。 入手先 BKPFまたはRBKPにある仕入先番号(LIFNR)を使って、仕入先マスターデータテーブルLFA1のNAME1フィールドから取得します。 例 オフィス用品株式会社グローバルコンサルティンググループ機械部品有限会社 | |||
| 会社コード CompanyCode | 請求書を処理する組織単位です。 | ||
| 説明 会社コードは、外部報告用の完全で独立した一連の勘定を作成できる最小の組織単位です。買掛金業務では、仕入先への支払い義務を負う法人を表します。 会社コード別に分析すると、組織内の法人間でプロセスのパフォーマンスを比較できます。標準プロセスに沿っている部門や、効率が高い部門、サイクルタイムや手戻り率が高い部門を特定するのに役立ちます。 重要な理由 法人間でプロセスのパフォーマンスを比較し、地域や事業部門に固有の問題や優れた取り組みを特定できます。 入手先 伝票ヘッダーテーブルにあります。主に、FI請求書ではBKPF-BUKRS、MM請求書ではRBKP-BUKRSを参照します。 例 10001710US01DE01 | |||
| 発注書番号 PurchaseOrderNumber | 該当する場合、請求書に関連付けられた発注書を一意に識別する番号です。 | ||
| 説明 この属性は、請求書と事前承認済みの発注書(PO)を関連付けます。発注書番号の有無が、発注書・請求書・入庫記録の3点照合の基準となります。 コンプライアンスと効率の分析に欠かせない属性です。「発注書なし請求書の割合」の重要業績評価指標(KPI)を算出し、調達ポリシーの遵守状況を測定できます。また、「3点照合のパフォーマンス」ダッシュボードで、発注書に基づく請求書の照合プロセスを分析する際にも基本となります。 重要な理由 3点照合の効率分析や、発注書なしで処理された請求書の特定による調達ポリシーの遵守状況の測定に欠かせません。 入手先 請求書明細テーブルにあります。例:MM請求書ではRSEG-EBELN、FI請求書ではBSEG-EBELN。 例 45000012344500005678 | |||
| 請求書の支払期限 InvoiceDueDate | 仕入先への請求書の支払い期限となる日付です。 | ||
| 説明 請求書の支払期限は、延滞料金を避け、仕入先との良好な関係を保つために支払いを済ませる期限です。請求書の基準日と仕入先との合意に基づく支払条件から算出します。 「支払いコンプライアンスと経過期間」ダッシュボードや「期限内支払い率」の重要業績評価指標(KPI)に欠かせない日付です。支払期限と実際の支払日を比較すると、期限内、期限前、期限後のどのタイミングで支払いが行われているかが分かり、財務面と仕入先との関係に及ぼす影響を分析できます。 重要な理由 期限内支払いの分析の基準となり、支払いパフォーマンスや仕入先との関係、延滞料金への影響を測定できます。 入手先 この日付は計算される場合があります。正味支払期限はBSEG-NETDTフィールドにあります。また、支払基準日(BSEG-ZFBDT)と支払条件(BSEG-ZTERM)から算出することもできます。 例 2023-10-312023-11-152024-01-10 | |||
| 請求書金額 InvoiceAmount | 元の伝票通貨で表示した請求書の税込み総額です。 | ||
| 説明 仕入先が提出した請求書の総額です。控除や割引を適用する前の、商品・サービスの費用、税金、その他の料金が含まれます。 請求書金額は、幅広い分析に使われる重要な財務属性です。高額な請求書の優先順位付け、プロセス遅延による財務的影響(例:高額請求書の延滞料金)の把握、プロセスの分類(例:「高額な請求書は異なる承認経路をたどるか」)に役立ちます。二重支払いの可能性を特定するうえでも欠かせません。 重要な理由 プロセスの財務的な背景を示し、金額に基づく分析や高額請求書の優先順位付け、財務的影響の定量化を可能にします。 入手先 MM請求書ではRBKP-RMWWR(請求書総額)などのテーブルにあります。FI請求書では、BSEGの明細(WRBTRフィールド)から算出します。 例 1500.00250.7512345.50 | |||
| 仕入先請求書番号 VendorInvoiceNumber | 仕入先が請求書に記載した番号です。 | ||
| 説明 仕入先の会計システムで使用されている参照番号で、紙または電子形式の請求書に記載されています。請求書の受領時に手入力するか、OCRで読み取ります。 この項目は、日常業務と分析の両方で非常に重要です。特に、「重複請求書の支払い可能性」ダッシュボードで役立ちます。重複を検出する一般的な方法は、仕入先名、仕入先請求書番号、請求金額が同じ社内請求書を複数検索することです。請求書を照合する際の主要な外部参照番号です。 重要な理由 重複支払いの可能性を検出するための重要な項目であり、仕入先との連絡に使う主要な外部参照番号です。 入手先 伝票ヘッダーの「参照」項目(通常はBKPF-XBLNR)に保存されています。 例 INV-2023-9876733401120231015-001 | |||
| 割引適用の有無 DiscountTaken | 早期支払い割引が適用されたかどうかを示す真偽値です。 | ||
| 説明 この属性は、請求書の支払い時に現金割引が実際に適用されたかどうかを示します。買掛金プロセスの財務効率を測定するうえで重要な項目です。 このフラグは、「早期支払い割引の適用率」の重要業績評価指標(KPI)の中核となります。支払条件に基づいて割引対象の請求書を絞り込み、このフラグを分析することで、削減できた金額と適用機会を逃した件数を正確に算出できます。これにより、買掛金業務の実績を明確な数値で把握できます。 重要な理由 利用可能な早期支払い割引を適用できた割合を直接測定できます。これは会社の収益に直接影響します。 入手先 支払伝票の割引額項目(BSEG-SKNTO)が0より大きいかどうかを確認して算出します。 例 truefalse | |||
| 支払ブロック理由 BlockingReason | 請求書の支払いがブロックされた理由です。不一致があることを示します。 | ||
| 説明 請求書が3点照合などの検証に合格しない場合、支払いがブロックされます。支払ブロック理由には、数量の不一致、価格差異、入庫記録の欠落など、問題の内容が示されます。 この属性は、「請求書の不一致に伴う手戻り分析」ダッシュボードで重要な役割を果たします。支払ブロック理由ごとの発生頻度を分析すると、プロセスの非効率を招く根本原因を特定できます。たとえば、「価格差異」が頻繁に発生している場合、購買システムのマスターデータに問題がある可能性があります。 重要な理由 請求書の不一致や手戻りの根本原因を直接把握できるため、対象を絞ったプロセス改善につなげられます。 入手先 RSEGなどの請求書明細テーブルで、SPGR*で始まる項目(SPGRP、SPGRQ、SPGRTなど)に保存されています。RBKP_BLOCKEDにも記録される場合があります。 例 価格の不一致数量の不一致入庫記録の欠落 | |||
| 支払条件 PaymentTerms | 請求書の支払いに関して仕入先と合意した条件です。通常、早期支払い割引の条件も含まれます。 | ||
| 説明 支払条件では、支払期日や早期支払い割引の適用条件を定めます。たとえば、「Z001」は「30日以内に支払い、10日以内の支払いで2%割引」を意味する場合があります。 この属性は、「早期支払い割引の適用率」ダッシュボードの基礎となります。支払条件を分析すると、割引の対象となる請求書をすべて特定できます。対象となる請求書と実際に適用された割引を比較することで、割引の適用漏れによる損失を把握し、支払いプロセスの効率を測定できます。 重要な理由 早期支払い割引の適用機会を分析し、支払いプロセスの財務面の実績を測定して、割引の適用漏れを特定するうえで欠かせません。 入手先 仕入先明細のテーブルBSEG-ZTERM、または請求書ヘッダーのRBKP-ZTERMにあります。 例 Z0010001NT30 | |||
| 支払遅延の有無 IsLatePayment | 請求書の支払いが支払期日を過ぎたかどうかを示す真偽値です。 | ||
| 説明 この計算属性は、請求書の支払いが正式な支払期日を過ぎたかどうかを示す真偽値です。「消込日」と「請求書の支払期日」を比較して算出します。 このフラグを使うと、「支払いコンプライアンスと滞留期間」ダッシュボードや「期日どおりの支払率」の重要業績評価指標(KPI)を簡単に分析できます。支払遅延の件数や期日どおりに支払われた割合を集計し、支払遅延の多い仕入先や会社コードを特定できます。 重要な理由 支払条件への適合状況を直接測定し、期日どおりの支払率の算出を簡素化するとともに、支払い実績に課題のある領域の特定に役立ちます。 入手先 計算属性です。ロジック:IF ClearingDate > InvoiceDueDate THEN true ELSE false。 例 truefalse | |||
| 消込日 ClearingDate | 支払いが行われ、未消込項目から請求書が消し込まれた日付です。 | ||
| 説明 消込日は、請求書の決済が完了した日を示します。「支払い消込」アクティビティが発生した日であり、通常、請求書処理が正常に完了するまでの最後のステップにあたります。 この日付を使って実際の支払日を算出し、請求書の支払期日と比較します。そのため、「期日どおりの支払率」の重要業績評価指標(KPI)や、支払い実績に関する分析に欠かせません。また、請求書処理のエンドツーエンドのサイクルタイムを算出する際の終了日にもなります。 重要な理由 請求書の最終決済日を示します。サイクルタイムの算出終了日となり、期日どおりの支払いを分析する基準にもなります。 入手先 仕入先の場合、BSAK-AUGDTなどの消込済み項目のテーブルにあります。 例 2023-10-282023-11-142024-01-09 | |||
| 自動処理かどうか IsAutomated | 担当者ではなくシステムがアクティビティを自動実行したかどうかを示すフラグです。 | ||
| 説明 この真偽値属性は、人が開始したアクティビティと、システムジョブ、ワークフロー、ボットが実行したアクティビティを区別します。たとえば、自動支払い実行やシステムによる請求書の転記には、自動処理のフラグが設定されます。 この属性を分析すると、買掛金プロセスの自動化の度合いを把握できます。自動化施策の成果測定、自動処理と手作業の効率比較、さらなる自動化の機会の特定に利用できます。 重要な理由 プロセスの自動化の度合いを測定し、自動化の効果を分析するとともに、さらなる改善の機会を特定できます。 入手先 ユーザー名(例:「SAP_SYSTEM」や「BATCHUSER」などのシステムユーザーID)や、自動ジョブに関連付けられた特定のトランザクションコードから判定します。 例 truefalse | |||
| 請求書伝票タイプ InvoiceDocumentType | SAPでの処理方法を制御する、請求書文書の分類です。 | ||
| 説明 伝票タイプは、会計伝票を分類するSAPの重要な設定項目です。たとえば、仕入先請求書には通常「KR」、MM請求書には「RE」、仕入先クレジットメモには「KG」を使用します。伝票タイプによって、番号範囲や必須フィールドなどが決まります。 プロセス分析で伝票タイプを使って絞り込むと、請求書の種類ごとにプロセスの流れを比較できます。たとえば、クレジットメモの承認プロセスは通常の請求書とは異なる場合があります。「請求書の承認経路のバリアント」ダッシュボードで役立ちます。 重要な理由 請求書の種類ごとの処理方法に基づいてプロセスを分類し、処理経路やサイクルタイムの違いを明らかにできます。 入手先 伝票ヘッダーテーブルのBKPF-BLARTフィールドから直接取得します。 例 KRREKG | |||
| 請求書通貨 InvoiceCurrency | 請求金額の通貨コードです(USD、EURなど)。 | ||
| 説明 この属性は、請求金額の通貨を示します。金額を扱う際に必要な情報です。 複数の国で事業を展開する組織では、通貨を考慮せずに請求書を分析すると、誤った解釈につながる可能性があります。この項目を使うと、金額を単一の報告通貨に換算するか、通貨別に分析を分けて地域ごとの財務活動を把握できます。 重要な理由 請求金額の通貨を確認できるため、特に複数の国で事業を展開する場合に、正確な財務分析と報告に役立ちます。 入手先 主に伝票ヘッダーテーブルのBKPF-WAERSまたはRBKP-WAERSにあります。 例 USDEURGBPJPY | |||
買掛金の請求書処理に関するアクティビティ
| アクティビティ | 説明 | ||
|---|---|---|---|
| 支払いを実行 | 請求書に対する支払いが行われた状態です。支払い実行が完了し、支払い文書が作成・転記された時点で記録されます。 | ||
| 重要な理由 このアクティビティは、キャッシュフロー分析や、支払日と請求書の支払期限を比較して「期限内支払い率」の重要業績評価指標(KPI)を測定するうえで欠かせません。 入手先 請求書の消込に使用された支払い文書の転記日から取得します。支払い文書番号は、請求書明細(BSEG)の消込伝票フィールド(AUGBL)に関連付けられています。 記録 請求書明細を消し込む支払い文書の転記日(BUDAT)を特定します。 イベントタイプ explicit | |||
| 支払いを消込 | このアクティビティは、補助元帳で支払いと請求書を照合し、請求書を最終的に決済したことを示します。プロセスの完了を表します。 | ||
| 重要な理由 プロセスの確定した終了点となるこのアクティビティは、正確なエンドツーエンドのサイクルタイムを算出するうえで欠かせません。債務が決済されたことを確認できます。 入手先 請求書文書の仕入先明細(テーブルBSEG)にある消込日(AUGDT)フィールドに値が入力されたことを示す、明示的なイベントです。 記録 請求書明細の消込日(BSEG-AUGDT)を使用します。 イベントタイプ explicit | |||
| 請求書の支払いをブロック | システムまたは担当者が請求書に支払いブロックを設定し、支払いを停止した状態です。通常、価格や数量の不一致、承認の不足などが原因です。 | ||
| 重要な理由 問題や手戻りを示す重要な指標です。ブロックの理由と期間を分析すると、支払い遅延やプロセスの非効率性の根本原因を特定できます。 入手先 会計伝票の仕入先明細(テーブルBSEG)にある支払いブロックキー(ZLSPR)フィールドに、明示的なステータスとして記録されます。 記録 BSEG-ZLSPRフィールドにブロック理由が入力された際、変更伝票に記録されます。 イベントタイプ explicit | |||
| 請求書を取り消し | 請求書文書が反対仕訳され、財務上の影響が取り消された状態です。誤入力や仕入先との紛争などが原因で発生する、プロセスの別の終了状態です。 | ||
| 重要な理由 取消を追跡すると、重複申請や請求書データの誤りなど、プロセスが失敗した理由を特定できます。上流工程の問題を示す手がかりにもなります。 入手先 反対仕訳文書が作成された時点で明示的に記録されます。元の文書ヘッダー(BKPF)には、反対仕訳文書番号(STBLG)と取消理由が入力されます。 記録 元の文書ヘッダー(BKPF-STBLG)に関連付けられた反対仕訳文書の転記日を特定します。 イベントタイプ explicit | |||
| 請求書を受領 | このアクティビティは、手入力またはOCR/VIMなどの自動連携によって、SAPに請求書文書が作成されたことを示します。通常、会計伝票ヘッダーの作成日時からこのイベントを記録します。 | ||
| 重要な理由 プロセスの開始点となるこのアクティビティは、請求書処理全体のサイクルタイムや処理量を測定するうえで欠かせません。 入手先 会計伝票ヘッダーテーブル(BKPF)の伝票作成日(CPUDT)と作成時刻(CPUTM)から、このイベントを記録します。 記録 請求書文書の作成日時(BKPF-CPUDT、BKPF-CPUTM)を使用します。 イベントタイプ explicit | |||
| 請求書を承認 | ワークフローシステムで必要な承認がすべて完了した状態です。通常、請求書を転記する、または支払いブロックを解除する前の最終手順です。 | ||
| 重要な理由 この重要な節目は、承認サイクルの終了を示します。承認依頼から承認までの時間は、効率を測る重要な指標です。 入手先 SAP Business Workflowログの完了または最終リリースの記録から取得します。または、承認依頼後に支払いブロックが解除されたことから判定できます。 記録 SAPワークフローログからワークフロー完了イベントを抽出するか、最終的な「リリース」イベントを特定します。 イベントタイプ explicit | |||
| 請求書を転記 | 請求書が総勘定元帳に正式に記録され、金銭債務が計上された状態です。保留登録された文書を転記する場合と、直接転記する場合があります。 | ||
| 重要な理由 これは財務上の重要な節目です。会社の支払い義務が確定し、多くの場合、支払い予定を組む前提条件となります。 入手先 会計伝票ヘッダー(BKPF)の転記日(BUDAT)から、このイベントを特定します。転記済み文書の伝票ステータス(BKPF-BSTAT)は空欄です。 記録 保留登録されていない文書(BKPF-BSTATが空欄)の転記日(BKPF-BUDAT)を使用します。 イベントタイプ explicit | |||
| 不一致を解消 | このアクティビティは、支払いブロックの原因となった可能性のある問題を調査し、解消したことを示します。請求書の支払いブロックが解除された時点で記録されます。 | ||
| 重要な理由 この手戻りの流れを追跡することは、「請求書の不一致と手戻り分析」ダッシュボードに欠かせません。エラー修正にかかった時間と労力を定量化できます。 入手先 支払いブロックの解除を示す変更伝票から判定します。主な情報源は、BSEG-ZLSPRフィールドの変更ログです。 記録 テーブルBSEGの変更伝票を特定し、ZLSPRフィールドの値が入力済みから空欄に変更された記録を確認します。 イベントタイプ inferred | |||
| 入庫記録との照合完了 | このアクティビティは、請求書の数量と金額が対応する入庫文書と照合されたことを示します。3点照合における最終確認です。 | ||
| 重要な理由 このアクティビティを追跡すると、3点照合の非効率な箇所を特定し、実際の入庫内容と仕入先の請求内容の不一致を把握できます。 入手先 請求書明細に入庫の品目伝票参照が存在することから判定します。多くの場合、発注書の明細履歴を通じて関連付けられています。 記録 請求書明細に入庫文書の参照が存在することから判定します(例:MIRO請求書のRSEG)。 イベントタイプ inferred | |||
| 支払い提案を作成 | 請求書が支払い実行(例:F110)の支払い提案に含まれた状態です。支払い実行の最終処理を待ち、支払い対象として登録されています。 | ||
| 重要な理由 このアクティビティは、未決済債務が支払い準備中の項目に移る過程を示し、支払い業務の効率分析に役立ちます。 入手先 このイベントは、支払い実行データテーブル、特にREGUP(支払いプログラムの処理済み明細)とREGUH(ヘッダー)に明示的に記録されます。 記録 支払い実行を示すREGUHの記録に対応して、請求書がテーブルREGUPに現れた時点を特定します。 イベントタイプ explicit | |||
| 発注書との照合完了 | このアクティビティは、請求書と対応する発注書の照合が完了したことを示します。調達に基づく請求書の3点照合における重要な手順です。 | ||
| 重要な理由 このアクティビティを分析すると、照合プロセスの効率を測定できます。また、「3点照合のパフォーマンス」や「発注書なし請求書の割合」の重要業績評価指標(KPI)を算出するうえでも基本となります。 入手先 テーブルBSEGまたはACDOCAの請求書明細に、有効な発注書番号(EBELN)と明細番号(EBELP)が含まれている場合に、このイベントを判定します。 記録 請求書文書の作成時に、発注書参照(BSEG-EBELN)が存在することから判定します。 イベントタイプ inferred | |||
| 請求書の支払期限を超過 | 請求書の正味支払期限を過ぎても支払いが消し込まれていないことを示す、計算上のイベントです。支払いの遅延または期限超過を表します。 | ||
| 重要な理由 「支払いコンプライアンスと経過期間」ダッシュボードに欠かせないアクティビティです。期限超過の請求書を早期に特定・管理し、支払い遅延の根本原因を分析できます。 入手先 SAPに明示的なイベントとして記録されるものではありません。システムの現在日付と正味支払期限(BSEG-ZFBDT、または基準日と支払条件から算出)を比較して計算します。 記録 イベントのタイムスタンプが請求書の正味支払期限を過ぎたときに発生する、計算上のイベントです。 イベントタイプ calculated | |||
| 請求書を保留登録 | システムに入力済みで、総勘定元帳にはまだ転記されていない請求書を示します。不完全な文書を後で処理または承認するために保存する目的で、この手順を行うことがあります。 | ||
| 重要な理由 保留中の請求書を追跡すると、正式な転記処理が始まる前の遅延を特定できます。また、データの不足や初期検証の問題を把握する手がかりにもなります。 入手先 会計伝票ヘッダー(BKPF)の伝票ステータスフィールド(BKPF-BSTAT = 'V' は保留登録)から、このステータスを判定します。ステータスが設定された時点でイベントが発生します。 記録 テーブルBKPFの変更伝票を特定し、BSTATフィールドが'V'(Vor-erfasst/事前入力済み)に設定された記録を確認します。 イベントタイプ inferred | |||
| 請求書を却下 | 承認者が承認ワークフロー中に請求書を却下した状態です。通常、請求書は修正または確認のため処理担当者に差し戻されます。 | ||
| 重要な理由 却下を追跡すると、承認プロセスでの手戻りを把握できます。また、ポリシーへの不適合や請求書の誤った勘定コード設定を示す場合もあります。 入手先 請求書に関連付けられたSAP Business Workflowログに、特定の結果イベントとして記録されます。 記録 SAPワークフローログから、ワークフローの「却下」ステータスイベントを抽出します。 イベントタイプ explicit | |||
| 請求書を承認ワークフローに回付 | 業務ルールに基づく必要な承認を得るため、請求書がワークフローに送信された状態です。承認サブプロセスの開始を示します。 | ||
| 重要な理由 このアクティビティは、「請求書の平均承認時間」の重要業績評価指標(KPI)を測定し、承認のボトルネックを分析する際の起点となります。 入手先 請求書オブジェクト(例:BUS2081)に関連付けられたワークフローインスタンスの開始を記録する、SAP Business Workflowログ(SWW*テーブル)から取得できます。 記録 請求書文書に関連付けられたSAPワークフローログ(例:テーブルSWW_WIHEAD)から、ワークフローの開始イベントを抽出します。 イベントタイプ explicit | |||
データ抽出ガイド
ステップ
- 前提条件とアクセス権:CDSビューが格納されているSAP S/4HANAデータベーススキーマ(通常はSAPABAP1など)への読み取りアクセス権を持つユーザーをご用意ください。また、SAP HANAデータベースに接続できるSQLクライアント(SAP HANA Studio、DBeaverなど)も必要です。
- 主要なCDSビューの確認:抽出に使用する主なCDSビューは、I_JournalEntry、I_JournalEntryItem、I_SupplierInvoiceAPI01、I_ChangeDocument、I_WorkflowStatusDetails、I_PaymentProposalItemです。それぞれの主要フィールドを確認してください。
- クエリ範囲の設定:SQLクライアントを開き、SAP HANAデータベースに接続します。クエリ全体を実行する前に、抽出範囲を設定してください。ソースシステム識別子、請求書の日付範囲(CreationDateTime)、対象の会社コードを指定します。
- メインクエリの準備:クエリのセクションにあるSQLクエリ全体をSQLクライアントにコピーします。このクエリでは、共通テーブル式(CTE)を使って対象となる請求書を選び、その後、15種類のアクティビティのデータを統合してイベントログを作成します。
- クエリパラメーターの設定:コピーしたSQLクエリ内のプレースホルダーを確認します。「[YYYY-MM-DD]」を分析期間の開始日と終了日に置き換えます。「[Your Company Code 1]」「[Your Company Code 2]」は、分析対象のSAP会社コードの一覧に置き換えてください。
- 抽出クエリの実行:SQLクエリ全体を実行します。データ量や指定した日付範囲によって、完了まで数分から数時間かかる場合があります。
- 結果の初期確認:クエリの実行後、出力の先頭数百行を確認します。データに一貫性があること、想定どおりに各列が入力されていること、複数のActivityName値が含まれていることを確認してください。
- イベントログのエクスポート:SQLクライアントから結果全体をCSVファイルにエクスポートします。文字化けを防ぐため、UTF-8でエンコードしてください。たとえば、sap_s4hana_ap_event_log.csvのように内容が分かるファイル名を付けます。
- アップロードの準備:プロセスマイニングツールにアップロードする前に、CSVファイルの列見出しが必要な属性名(Invoice、ActivityName、EventTime、SourceSystem、LastDataUpdate、UserNameなど)と完全に一致していることを確認します。
- プロセスマイニングツールへのアップロード:作成したCSVファイルをプロセスマイニングプラットフォームにアップロードし、各列を対応するケースID、アクティビティ、タイムスタンプのフィールドに割り当てます。
設定
- 主要なCDSビュー:抽出には、標準のS/4HANA CDSビューを組み合わせて使用します。主なビューは次のとおりです。
- I_JournalEntryとI_JournalEntryItem:財務伝票のヘッダー、明細、転記情報、消込情報。
- I_SupplierInvoiceAPI01:PO参照や支払ブロックなど、MM(ロジスティクス)の請求書固有の詳細情報。
- I_ChangeDocument:支払ブロックの設定や解除など、変更が行われた正確なタイムスタンプ。
- I_WorkflowStatusDetails:請求書の承認ワークフローに関するイベント。
- I_PaymentProposalItem:請求書が支払実行の提案に含まれたタイミング。
- I_Supplier:VendorNameなどの仕入先マスターデータによる情報の補完。
- 日付範囲の絞り込み:データ量を抑えるため、日付範囲のフィルターを必ず設定してください。提供するクエリでは、Invoices_Base CTE内のCreationDateTimeで絞り込んでいます。初回の分析では、処理時間を運用しやすい範囲に保つため、3~6か月を推奨します。
- 必須フィルター:必ずCompanyCodeで絞り込んでください。すべての会社コードを一度に分析すると、処理が非常に遅くなるうえ、業務上の関連性が低い場合があります。また、JournalEntryTypeで仕入先関連の伝票(例:「KR」「RE」)だけを選択してください。
- 前提条件:クエリを実行するデータベースユーザーには、使用するすべてのCDSビューと基盤となるHANAスキーマに対するSELECT権限が必要です。SAP GUIでのアプリケーションレベルのアクセス権だけでは不十分です。
- パフォーマンスに関する考慮事項:I_ChangeDocumentへの直接クエリは、システムリソースを多く消費する場合があります。提供するクエリでは、先に請求書を絞り込むことで負荷を抑えています。データ量が非常に多い場合は、利用の少ない時間帯に実行するか、日付範囲を小分けにして抽出してください。
クエリの例 sql
-- Common Table Expression (CTE) to select the base set of AP Invoices
WITH Invoices_Base AS (
SELECT
I_JournalEntry.CompanyCode,
I_JournalEntry.AccountingDocument,
I_JournalEntry.FiscalYear,
CONCAT(I_JournalEntry.CompanyCode, CONCAT(I_JournalEntry.AccountingDocument, I_JournalEntry.FiscalYear)) AS InvoiceId,
I_JournalEntry.CreationDateTime,
I_JournalEntry.CreatedByUser,
I_JournalEntry.DocumentStatus,
I_JournalEntry.JournalEntryType,
I_JournalEntry.ReversalReferenceJournalEntry,
I_JournalEntry.IsReversed,
I_JournalEntry.ReversalDate,
IJE_ITEM.NetDueDate,
IJE_ITEM.Supplier,
SUP.SupplierName AS VendorName,
IJE_ITEM.AmountInCompanyCodeCurrency AS InvoiceAmount,
MM.PurchaseOrder AS PurchaseOrderNumber,
MM.PaymentBlockingReason
FROM I_JournalEntry
-- Join to get item details like due date and supplier
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON I_JournalEntry.CompanyCode = IJE_ITEM.CompanyCode
AND I_JournalEntry.AccountingDocument = IJE_ITEM.AccountingDocument
AND I_JournalEntry.FiscalYear = IJE_ITEM.FiscalYear
AND IJE_ITEM.IsSupplier = 'X'
-- Join to get vendor name from master data
LEFT JOIN I_Supplier AS SUP
ON IJE_ITEM.Supplier = SUP.Supplier
-- Join to get MM Invoice specific data like PO Number and Payment Block
LEFT JOIN I_SupplierInvoiceAPI01 AS MM
ON I_JournalEntry.AccountingDocument = MM.AccountingDocument
AND I_JournalEntry.CompanyCode = MM.CompanyCode
AND I_JournalEntry.FiscalYear = MM.FiscalYear
WHERE
I_JournalEntry.JournalEntryType IN ('KR', 'RE') -- Standard Vendor Invoice Types
AND I_JournalEntry.CompanyCode IN ('[Your Company Code 1]', '[Your Company Code 2]')
AND I_JournalEntry.CreationDateTime BETWEEN '[YYYY-MM-DD]T00:00:00Z' AND '[YYYY-MM-DD]T23:59:59Z'
)
-- Event: 1. Invoice Received
SELECT
B.InvoiceId AS "Invoice",
'Invoice Received' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
UNION ALL
-- Event: 2. Invoice Parked
SELECT
B.InvoiceId AS "Invoice",
'Invoice Parked' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.DocumentStatus = 'V' -- 'V' stands for Parked
UNION ALL
-- Event: 3. Purchase Order Matched
SELECT
B.InvoiceId AS "Invoice",
'Purchase Order Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PurchaseOrderNumber IS NOT NULL AND B.PurchaseOrderNumber <> ''
UNION ALL
-- Event: 4. Goods Receipt Matched
SELECT
B.InvoiceId AS "Invoice",
'Goods Receipt Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_SupplierInvoiceItemAPI01 AS MM_ITEM
ON B.AccountingDocument = MM_ITEM.AccountingDocument
AND B.FiscalYear = MM_ITEM.FiscalYear
WHERE MM_ITEM.GoodsReceipt IS NOT NULL AND MM_ITEM.GoodsReceipt <> ''
UNION ALL
-- Event: 5. Invoice Blocked For Payment
SELECT
B.InvoiceId AS "Invoice",
'Invoice Blocked For Payment' AS "ActivityName",
B.CreationDateTime AS "EventTime", -- Approximates block time as creation time if blocked on entry
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PaymentBlockingReason IS NOT NULL AND B.PaymentBlockingReason <> ''
UNION ALL
-- Event: 6. Discrepancy Resolved (Payment Block Removed)
SELECT
B.InvoiceId AS "Invoice",
'Discrepancy Resolved' AS "ActivityName",
CD.ChangeTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CD.UserName AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_ChangeDocument AS CD
ON CONCAT(B.CompanyCode, B.AccountingDocument, B.FiscalYear) = CD.ObjectValue
WHERE CD.ChangeDocumentObject = 'INVOICE'
AND CD.TableName = 'RBKP'
AND CD.FieldName = 'ZLSPR' -- Field for Payment Block
AND CD.NewFieldValue = '' -- Block was removed
UNION ALL
-- Event: 7, 8, 9. Workflow Events (Routed, Approved, Rejected)
SELECT
B.InvoiceId AS "Invoice",
CASE WF.WorkflowStatus
WHEN 'READY' THEN 'Invoice Routed For Approval'
WHEN 'APPROVED' THEN 'Invoice Approved'
WHEN 'REJECTED' THEN 'Invoice Rejected'
END AS "ActivityName",
WF.WorkflowStatusChangedDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
WF.WorkflowStatusChangedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_WorkflowStatusDetails AS WF
ON B.InvoiceId = WF.WorkflowScenarioInstance
WHERE WF.WorkflowStatus IN ('READY', 'APPROVED', 'REJECTED')
UNION ALL
-- Event: 10. Invoice Posted
SELECT
B.InvoiceId AS "Invoice",
'Invoice Posted' AS "ActivityName",
JE.PostingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntry AS JE
ON B.AccountingDocument = JE.AccountingDocument
AND B.CompanyCode = JE.CompanyCode
AND B.FiscalYear = JE.FiscalYear
WHERE B.DocumentStatus <> 'V' -- Any status other than Parked is considered Posted for AP
UNION ALL
-- Event: 11. Payment Proposal Created
SELECT
B.InvoiceId AS "Invoice",
'Payment Proposal Created' AS "ActivityName",
PPI.PaymentProposalRunDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
PPI.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_PaymentProposalItem AS PPI
ON B.CompanyCode = PPI.CompanyCode
AND B.AccountingDocument = PPI.AccountingDocument
AND B.FiscalYear = PPI.FiscalYear
UNION ALL
-- Event: 12. Payment Executed
-- This links the invoice to its clearing document, which is the payment document
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Executed' AS "ActivityName",
CLEAR_JE.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CLEAR_JE.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
INNER JOIN I_JournalEntry AS CLEAR_JE
ON IJE_ITEM.ClearingJournalEntry = CLEAR_JE.AccountingDocument
AND IJE_ITEM.CompanyCode = CLEAR_JE.CompanyCode
WHERE IJE_ITEM.ClearingJournalEntry IS NOT NULL AND IJE_ITEM.ClearingJournalEntry <> ''
AND CLEAR_JE.JournalEntryType = 'KZ' -- Vendor Payment Document Type
UNION ALL
-- Event: 13. Invoice Due Date Passed
SELECT
B.InvoiceId AS "Invoice",
'Invoice Due Date Passed' AS "ActivityName",
ADD_DAYS(B.NetDueDate, 1) AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
'SYSTEM' AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE B.NetDueDate < CURRENT_DATE
AND IJE_ITEM.ClearingDate IS NULL -- Invoice is not yet cleared
UNION ALL
-- Event: 14. Payment Cleared
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Cleared' AS "ActivityName",
IJE_ITEM.ClearingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
IJE_ITEM.ChangedByUser AS "UserName", -- User who cleared it
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE IJE_ITEM.ClearingDate IS NOT NULL
UNION ALL
-- Event: 15. Invoice Cancelled
SELECT
B.InvoiceId AS "Invoice",
'Invoice Cancelled' AS "ActivityName",
B.ReversalDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName", -- User who created the original document
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.IsReversed = 'X'; ステップ
- 関連するSAP S/4HANAテーブルを含むSAP HANAスキーマへの直接読み取りアクセスが可能であることを確認します。接続文字列、認証情報、スキーマ名、およびBKPF、ACDOCAと、保留伝票、ワークフロー、購買、入庫、支払提案、消込、取消データ用に設定された追加テーブルを読み取る権限を用意してください。
- 実行前に、対象システムの技術データモデルを確認します。物理名、キー項目、タイムスタンプ項目、取消の関連付け、支払いの関連付け、システムで使用されるワークフローの永続化先を検証してください。クエリ内の角括弧付きプレースホルダーは、それぞれ対象システムのオブジェクト名またはフィールド名に置き換えます。ワークフローや保留伝票のデータが、共通の単一テーブルに格納されているとは限りません。
- 抽出パラメーターを設定します。[Start date]、[End date]、[Company code filter]、[Document type filter]、[Schema name]を指定してください。まず3~6か月の範囲で実行し、パフォーマンスとデータの網羅性を確認してから期間を延長します。
- SAP HANA Database Explorerなど、承認済みのSAP HANA SQLクライアントまたは認可されたSQL実行ツールでクエリを実行します。このクエリは、明示的に抽出した各アクティビティについて1行を出力します。ProcessMindがイベントを推定する仕組みには依存しません。
- 結果を検証します。Invoiceがケース識別子であること、ActivityNameに必要な15種類のアクティビティ名がすべて含まれていること、EventTimeが入力され時系列として妥当であること、SourceSystemがSAP S/4HANAを示していること、LastDataUpdateに抽出データの更新タイムスタンプが含まれていることを確認してください。データを読み込む前に、重複イベント、取消の関連付け、伝票の結合を確認します。
- 必要に応じて、システム固有のマッピングを適用します。たとえば、設定済みの保留伝票ソースをInvoice Parkedに、ワークフローソースをInvoice Routed For Approval、Invoice Approved、Invoice Rejectedに、支払いソースをPayment Proposal CreatedとPayment Executedに対応付けます。監査可能性が必要な場合は、ソース識別子を追加列に保持してください。
- 1行につき1イベントとなるよう、区切り形式のファイルまたはデータベースの結果セットとしてエクスポートします。UTF-8でエンコードし、タイムスタンプのタイムゾーンを統一してください。列名Invoice、ActivityName、EventTime、SourceSystem、LastDataUpdate、UserName、CompanyCode、VendorName、InvoiceAmount、PurchaseOrderNumber、InvoiceDueDateは正確に保持し、請求書ごとにアクティビティを集約しないでください。
- イベントログをProcessMindにアップロードし、Invoiceをケース識別子、ActivityNameをアクティビティ列、EventTimeをイベント時刻列として設定します。任意の属性も対応するフィールドに割り当てられていることを確認してください。ProcessMindはイベントログをそのまま読み込むため、可視化するすべてのアクティビティがアップロード前に行として含まれている必要があります。
設定
- 日付範囲:まず3~6か月を対象にします。抽出するアクティビティに応じて、転記日、伝票作成日、または関連するソースイベントの日付を使います。クエリの実行時間とソースデータの保持期間を確認してから、範囲を広げてください。
- 会社コードによる絞り込み:[Company code filter]を設定し、必要な会社コードに抽出対象を限定します。制限が不要な場合も、本番環境に対する無制限のクエリではなく、管理された方法で全会社を選択してください。
- 伝票による絞り込み:対象システムで仕入先請求書、クレジットメモ、保留伝票、支払伝票、取消に使用される伝票タイプを確認してから、[Document type filter]を設定してください。
- スキーマとオブジェクトのマッピング:[Schema name]と角括弧付きのソースオブジェクトまたはフィールドはすべて、対象のSAP S/4HANAシステムで確認した値に置き換えます。HANAへの直接クエリは、システムで有効化されているアプリケーション、拡張機能、ワークフロー設計、データモデルに合わせて調整する必要があります。
- タイムスタンプの処理:すべてのソースタイムスタンプのタイムゾーンを統一します。日付しかない場合は、既定の時刻を文書化し、その制約をデータ辞書に記録してください。
- イベントの扱い:各アクティビティを個別の行として抽出します。複数のアクティビティを1つの請求書レコードにまとめないでください。また、照合、承認、支払期日、消込のイベントをProcessMindが導出することは想定しないでください。
- 支払期日イベント:設定した評価時刻より前に支払期日を迎え、その時刻までに消込イベントがない請求書に限り、Invoice Due Date Passedを生成します。この計算にはクエリ内の[Evaluation timestamp]を使用します。
- パフォーマンス:初期の対象期間と会社の範囲を絞り、インデックスまたはパーティションに関連するフィールドでフィルターを設定し、不要な列の取得を避け、承認済みのレポート実行時間帯に実行してください。本番クエリが合意した実行時間を超える場合は、ソースデータの一部をステージングすることを検討してください。
- 更新方法:LastDataUpdateには抽出の実行時刻を設定します。差分読み込みでは、関連するソース変更タイムスタンプに基づくウォーターマークを保持し、遅れて反映される更新や取消を取り込めるよう、遡及期間を設けてください。
- 前提条件:必要なデータベース権限、承認済みの本番環境アクセス、対象システムのUniversal Journal設定に関する知識、設定済みの保留伝票、購買、入庫、ワークフロー、支払い、消込、取消データソースへのアクセス、および該当するSAPライセンスやガバナンス上の承認。
クエリの例 sql
WITH
params AS (
SELECT
TO_DATE('[Start date]') AS start_date,
TO_DATE('[End date]') AS end_date,
TO_TIMESTAMP('[Evaluation timestamp]') AS evaluation_ts,
TO_TIMESTAMP('[Extraction timestamp]') AS extraction_ts
FROM DUMMY
),
base_invoice AS (
SELECT
b.mandt,
b.bukrs,
b.belnr,
b.gjahr,
b.bldat,
b.budat,
b.cpudt,
b.cputm,
b.usnam,
b.blart,
b.xblnr,
b.stblg,
b.stjah,
a.lifnr,
a.wrbtr,
a.waers,
a.zfbdt,
a.zbd1t,
a.zbd2t,
a.zbd3t,
a.ebeln,
a.ebelp,
a.augbl,
a.augdt,
a.buzei,
v.name1 AS vendor_name,
CASE
WHEN a.zfbdt IS NOT NULL THEN ADD_DAYS(a.zfbdt, COALESCE(a.zbd1t, 0))
ELSE NULL
END AS invoice_due_date
FROM [Schema name].BKPF b
INNER JOIN [Schema name].ACDOCA a
ON a.mandt = b.mandt
AND a.rbukrs = b.bukrs
AND a.belnr = b.belnr
AND a.gjahr = b.gjahr
LEFT JOIN [Schema name].[Vendor master table] v
ON v.[Vendor key field] = a.lifnr
CROSS JOIN params p
WHERE b.bukrs IN ([Company code filter])
AND b.blart IN ([Document type filter])
AND b.cpudt BETWEEN p.start_date AND p.end_date
),
invoice_received AS (
SELECT DISTINCT
CAST(belnr AS NVARCHAR(40)) AS invoice,
'Invoice Received' AS activity_name,
TO_TIMESTAMP(TO_VARCHAR(cpudt, 'YYYY-MM-DD') || ' ' || COALESCE(TO_VARCHAR(cputm), '00:00:00')) AS event_time,
CAST(usnam AS NVARCHAR(80)) AS user_name,
bukrs AS company_code,
vendor_name,
wrbtr AS invoice_amount,
waers AS document_currency,
CAST(ebeln AS NVARCHAR(40)) AS purchase_order_number,
invoice_due_date
FROM base_invoice
),
invoice_parked AS (
SELECT
CAST([Parked invoice key field] AS NVARCHAR(40)) AS invoice,
'Invoice Parked' AS activity_name,
[Parked event timestamp field] AS event_time,
CAST([Parked user field] AS NVARCHAR(80)) AS user_name,
[Parked company code field] AS company_code,
[Parked vendor name field] AS vendor_name,
[Parked amount field] AS invoice_amount,
[Parked currency field] AS document_currency,
CAST([Parked purchase order field] AS NVARCHAR(40)) AS purchase_order_number,
[Parked due date field] AS invoice_due_date
FROM [Schema name].[Parked document source]
WHERE [Parked event date field] BETWEEN (SELECT start_date FROM params) AND (SELECT end_date FROM params)
AND [Parked company code field] IN ([Company code filter])
),
purchase_order_matched AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Purchase Order Matched' AS activity_name,
COALESCE([Purchase order match timestamp field], TO_TIMESTAMP(TO_VARCHAR(i.cpudt, 'YYYY-MM-DD') || ' ' || COALESCE(TO_VARCHAR(i.cputm), '00:00:00'))) AS event_time,
CAST(COALESCE([Purchase order match user field], i.usnam) AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrBtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Purchase order match source] m
ON m.[Invoice document key field] = i.belnr
AND m.[Invoice company code field] = i.bukrs
AND m.[Invoice fiscal year field] = i.gjahr
WHERE i.ebeln IS NOT NULL
),
goods_receipt_matched AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Goods Receipt Matched' AS activity_name,
[Goods receipt match timestamp field] AS event_time,
CAST(COALESCE([Goods receipt match user field], i.usnam) AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Goods receipt match source] g
ON g.[Invoice document key field] = i.belnr
AND g.[Invoice company code field] = i.bukrs
AND g.[Invoice fiscal year field] = i.gjahr
WHERE i.ebeln IS NOT NULL
),
invoice_blocked AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Invoice Blocked For Payment' AS activity_name,
[Payment block timestamp field] AS event_time,
CAST(COALESCE([Payment block user field], i.usnam) AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Payment block source] b
ON b.[Invoice document key field] = i.belnr
AND b.[Invoice company code field] = i.bukrs
AND b.[Invoice fiscal year field] = i.gjahr
WHERE [Payment block value field] IS NOT NULL
),
discrepancy_resolved AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Discrepancy Resolved' AS activity_name,
[Payment block removal timestamp field] AS event_time,
CAST(COALESCE([Payment block removal user field], i.usnam) AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Payment block history source] h
ON h.[Invoice document key field] = i.belnr
AND h.[Invoice company code field] = i.bukrs
AND h.[Invoice fiscal year field] = i.gjahr
WHERE [Previous payment block value field] IS NOT NULL
AND [New payment block value field] IS NULL
),
invoice_routed_for_approval AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Invoice Routed For Approval' AS activity_name,
[Workflow routed timestamp field] AS event_time,
CAST([Workflow initiator field] AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Workflow event source] w
ON w.[Invoice document key field] = i.belnr
AND w.[Invoice company code field] = i.bukrs
AND w.[Invoice fiscal year field] = i.gjahr
WHERE [Workflow event type field] = '[Workflow routed event value]'
),
invoice_approved AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Invoice Approved' AS activity_name,
[Workflow approval timestamp field] AS event_time,
CAST([Workflow approver field] AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Workflow event source] w
ON w.[Invoice document key field] = i.belnr
AND w.[Invoice company code field] = i.bukrs
AND w.[Invoice fiscal year field] = i.gjahr
WHERE [Workflow event type field] = '[Workflow approved event value]'
),
invoice_rejected AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Invoice Rejected' AS activity_name,
[Workflow rejection timestamp field] AS event_time,
CAST([Workflow rejector field] AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Workflow event source] w
ON w.[Invoice document key field] = i.belnr
AND w.[Invoice company code field] = i.bukrs
AND w.[Invoice fiscal year field] = i.gjahr
WHERE [Workflow event type field] = '[Workflow rejected event value]'
),
invoice_posted AS (
SELECT DISTINCT
CAST(belnr AS NVARCHAR(40)) AS invoice,
'Invoice Posted' AS activity_name,
TO_TIMESTAMP(TO_VARCHAR(budat, 'YYYY-MM-DD') || ' 00:00:00') AS event_time,
CAST(usnam AS NVARCHAR(80)) AS user_name,
bukrs AS company_code,
vendor_name,
wrbtr AS invoice_amount,
waers AS document_currency,
CAST(ebeln AS NVARCHAR(40)) AS purchase_order_number,
invoice_due_date
FROM base_invoice
WHERE stblg IS NULL
),
payment_proposal_created AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Payment Proposal Created' AS activity_name,
[Payment proposal timestamp field] AS event_time,
CAST([Payment proposal user field] AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Payment proposal source] p
ON p.[Invoice document key field] = i.belnr
AND p.[Invoice company code field] = i.bukrs
AND p.[Invoice fiscal year field] = i.gjahr
),
payment_executed AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Payment Executed' AS activity_name,
[Payment execution timestamp field] AS event_time,
CAST([Payment execution user field] AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
INNER JOIN [Schema name].[Payment execution source] p
ON p.[Invoice document key field] = i.belnr
AND p.[Invoice company code field] = i.bukrs
AND p.[Invoice fiscal year field] = i.gjahr
),
invoice_due_date_passed AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Invoice Due Date Passed' AS activity_name,
TO_TIMESTAMP(TO_VARCHAR(i.invoice_due_date, 'YYYY-MM-DD') || ' 23:59:59') AS event_time,
CAST(i.usnam AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
WHERE i.invoice_due_date IS NOT NULL
AND TO_TIMESTAMP(TO_VARCHAR(i.invoice_due_date, 'YYYY-MM-DD') || ' 23:59:59') < (SELECT evaluation_ts FROM params)
AND i.augbl IS NULL
),
payment_cleared AS (
SELECT DISTINCT
CAST(i.belnr AS NVARCHAR(40)) AS invoice,
'Payment Cleared' AS activity_name,
TO_TIMESTAMP(TO_VARCHAR(i.augdt, 'YYYY-MM-DD') || ' 00:00:00') AS event_time,
CAST(i.usnam AS NVARCHAR(80)) AS user_name,
i.bukrs AS company_code,
i.vendor_name,
i.wrbtr AS invoice_amount,
i.waers AS document_currency,
CAST(i.ebeln AS NVARCHAR(40)) AS purchase_order_number,
i.invoice_due_date
FROM base_invoice i
WHERE i.augbl IS NOT NULL
AND i.augdt IS NOT NULL
),
invoice_cancelled AS (
SELECT DISTINCT
CAST(belnr AS NVARCHAR(40)) AS invoice,
'Invoice Cancelled' AS activity_name,
TO_TIMESTAMP(TO_VARCHAR([Reversal posting date field], 'YYYY-MM-DD') || ' 00:00:00') AS event_time,
CAST(COALESCE([Reversal user field], usnam) AS NVARCHAR(80)) AS user_name,
bukrs AS company_code,
vendor_name,
wrbtr AS invoice_amount,
waers AS document_currency,
CAST(ebeln AS NVARCHAR(40)) AS purchase_order_number,
invoice_due_date
FROM base_invoice
WHERE stblg IS NOT NULL
),
all_events AS (
SELECT * FROM invoice_received
UNION ALL SELECT * FROM invoice_parked
UNION ALL SELECT * FROM purchase_order_matched
UNION ALL SELECT * FROM goods_receipt_matched
UNION ALL SELECT * FROM invoice_blocked
UNION ALL SELECT * FROM discrepancy_resolved
UNION ALL SELECT * FROM invoice_routed_for_approval
UNION ALL SELECT * FROM invoice_approved
UNION ALL SELECT * FROM invoice_rejected
UNION ALL SELECT * FROM invoice_posted
UNION ALL SELECT * FROM payment_proposal_created
UNION ALL SELECT * FROM payment_executed
UNION ALL SELECT * FROM invoice_due_date_passed
UNION ALL SELECT * FROM payment_cleared
UNION ALL SELECT * FROM invoice_cancelled
)
SELECT
invoice AS "Invoice",
activity_name AS "ActivityName",
event_time AS "EventTime",
'SAP S/4HANA' AS "SourceSystem",
(SELECT extraction_ts FROM params) AS "LastDataUpdate",
user_name AS "UserName",
company_code AS "CompanyCode",
vendor_name AS "VendorName",
invoice_amount AS "InvoiceAmount",
purchase_order_number AS "PurchaseOrderNumber",
invoice_due_date AS "InvoiceDueDate"
FROM all_events
WHERE invoice IS NOT NULL
AND event_time IS NOT NULL
ORDER BY "Invoice", "EventTime", "ActivityName"; ステップ
- 仕様と設計:コーディングの前に業務アナリストと連携し、必要な15種類のアクティビティそれぞれについて、正確な発生条件とデータ項目を確認します。対象となるSAPテーブル、伝票タイプ(例:「KR」「RE」)、会社コードを特定します。
- ABAPプログラムの作成:トランザクションコードSE38でABAPエディターを起動します。たとえばZ_PM_AP_INVOICE_EXTRACTのような新しい実行可能プログラムを作成します。内容が分かるタイトルを付け、アプリケーションを「財務会計」に設定します。
- 選択画面の定義:プログラム内でPARAMETERSおよびSELECT-OPTIONSキーワードを使い、請求書作成日の日付範囲、対象の会社コード(BUKRS)、関連する請求書伝票タイプ(BLART)を指定できる選択画面を定義します。アプリケーションサーバー上の出力ファイルパスを指定するパラメーターも追加します。
- データ宣言:必要な属性と推奨属性を含む最終イベントログ形式(例:TY_EVENT_LOG)に合わせて、内部テーブルの構造を定義します。BKPF、BSEG、RBKP、RSEG、CDHDR、CDPOS、REGUHなどのSAPソーステーブルから選択したデータを格納する内部テーブルも宣言します。
- メインデータの選択:選択画面の条件に基づき、RBKP(ロジスティクス請求書)とBKPF(財務請求書)から対象となる請求書を選択して、抽出処理を開始します。後続のデータ検索に使うため、請求書のキーを内部テーブルに格納します。
- アクティビティの順次抽出:対象となる各請求書について、業務アクティビティごとのタイムスタンプと詳細を取得します。たとえば、支払ブロックの変更にはCDHDRとCDPOS、支払実行データにはREGUHとREGUP、取消伝票の詳細にはBKPFを照会します。見つかったアクティビティごとに、新しいレコードを最終イベントログテーブルに追加します。
- 計算イベントのロジック:テーブルのフィールドに直接保存されていないアクティビティについて、ABAPの処理を実装します。「請求書の支払期日超過」イベントでは、請求書の支払期日(BSEG-ZFBDT+支払条件)と消込日(BSEG-AUGDT)を使います。消込日が支払期日より後の場合、タイムスタンプを支払期日に設定したイベントレコードを作成します。
- データ変換と補完:各アクティビティのデータを収集しながら、必要な属性をすべて入力します。LFA1から仕入先名を検索し、日付と時刻を1つのタイムスタンプ文字列に変換(CONCATENATE...INTO...)して、SourceSystemの値を設定します。
- 出力ファイルの作成:すべての請求書と対応するアクティビティを処理し、最終内部テーブルに収集したら、OPEN DATASET、LOOP AT ... TRANSFER、CLOSE DATASETステートメントを使って、選択画面で指定したアプリケーションサーバー上のパスにデータを書き込みます。
- ダウンロードとアップロードの準備:トランザクションコードCG3Yを使って、生成したファイルをアプリケーションサーバーからローカルマシンにダウンロードします。UTF-8でエンコードしたCSV形式で保存してください。プロセスマイニングツールにアップロードする前に、列見出しが必要な属性(Invoice、ActivityName、EventTimeなど)と一致していることを確認します。
設定
- 日付範囲:請求書作成日(BKPF-CPUDTまたはRBKP-CPUDT)に対する選択オプションP_CPUDTを定義します。初回の分析では、6~12か月分のデータを推奨します。
- 会社コード(P_BUKRS):特定の会社コードに絞り込むため、SELECT-OPTIONSパラメーターを必須にします。特別な必要がない限り、すべての会社コードを一度に処理することは推奨しません。
- 請求書伝票タイプ(P_BLART):対象となる請求書伝票タイプに絞り込むSELECT-OPTIONSパラメーターです。一般的なタイプには、「KR」(仕入先請求書)、「KG」(仕入先クレジットメモ)、「RE」(ロジスティクス請求書照合)があります。
- 実行モード:大量のデータを処理する場合は、フォアグラウンドのダイアログ処理でタイムアウトが発生しないよう、バックグラウンドジョブ(SM36/SM37)として実行してください。利用の少ない時間帯にスケジュールします。
- 出力ファイルパス:SAPアプリケーションサーバー上のファイルパスとファイル名(例:/tmp/ディレクトリ)を指定するPARAMETERです。ダウンロード前に、ここへファイルを書き込みます。
- 前提条件:レポートの実行ユーザーには、FI、CO、MMのテーブル(BKPF、BSEG、RBKP、RSEG、LFA1)、変更伝票テーブル(CDHDR、CDPOS)、ワークフローテーブルを読み取る権限が必要です。また、アプリケーションサーバーにファイルを書き込むには、権限オブジェクトS_DATASETが必要です。
クエリの例 abap
*&---------------------------------------------------------------------*
*& Report Z_PM_AP_INVOICE_EXTRACT
*&---------------------------------------------------------------------*
*& This report extracts Accounts Payable invoice lifecycle events for
*& process mining analysis.
*&---------------------------------------------------------------------*
REPORT z_pm_ap_invoice_extract.
*&---------------------------------------------------------------------*
*& Data Structures
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
invoice TYPE belnr_d,
activityname TYPE string,
eventtime TYPE string,
sourcesystem TYPE logsys,
lastdataupdate TYPE string,
username TYPE uname,
companycode TYPE bukrs,
vendorname TYPE name1_gp,
invoiceamount TYPE wrbtr,
purchaseordernumber TYPE ebeln,
invoiceduedate TYPE d,
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
DATA: gv_system_id TYPE logsys.
DATA: gv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_bukrs FOR bkpf-bukrs OBLIGATORY,
s_cpudt FOR bkpf-cpudt OBLIGATORY DEFAULT sy-datum,
s_blart FOR bkpf-blart.
PARAMETERS: p_fpath TYPE string OBLIGATORY DEFAULT '/tmp/ap_extract.csv'.
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
" Get System ID and Update Timestamp
CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
IMPORTING
own_logical_system = gv_system_id
EXCEPTIONS
own_logical_system_not_defined = 1
OTHERS = 2.
CONCATENATE sy-datum sy-uzeit INTO gv_last_update.
" Internal tables for SAP data
DATA: lt_bkpf TYPE TABLE OF bkpf,
lt_rbkp TYPE TABLE OF rbkp.
" Select base documents
SELECT * FROM bkpf INTO TABLE lt_bkpf
WHERE bukrs IN s_bukrs
AND cpudt IN s_cpudt
AND blart IN s_blart
AND ( blart = 'KR' OR blart = 'KG' ). " Example FI Invoice Types
SELECT * FROM rbkp INTO TABLE lt_rbkp
WHERE bukrs IN s_bukrs
AND cpudt IN s_cpudt
AND blart IN s_blart
AND blart = 'RE'. " Example MM Invoice Type
" --- Process each invoice document ---
LOOP AT lt_bkpf ASSIGNING FIELD-SYMBOL(<fs_bkpf>).
PERFORM process_invoice USING <fs_bkpf>.
ENDLOOP.
LOOP AT lt_rbkp ASSIGNING FIELD-SYMBOL(<fs_rbkp>).
PERFORM process_mm_invoice USING <fs_rbkp>.
ENDLOOP.
" Write output to file
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*& Form PROCESS_INVOICE (Handles FI Invoices)
*&---------------------------------------------------------------------*
FORM process_invoice USING iv_bkpf TYPE bkpf.
DATA: ls_bseg TYPE bseg,
ls_lfa1 TYPE lfa1,
ld_due_date TYPE d.
DATA: ls_event TYPE ty_event_log.
" Get Vendor and other details from first line item
SELECT SINGLE * FROM bseg INTO ls_bseg
WHERE bukrs = iv_bkpf-bukrs
AND belnr = iv_bkpf-belnr
AND gjahr = iv_bkpf-gjahr
AND koart = 'K'.
IF sy-subrc = 0.
SELECT SINGLE name1 FROM lfa1 INTO ls_lfa1-name1 WHERE lifnr = ls_bseg-lifnr.
CALL FUNCTION 'DETERMINE_DUE_DATE'
EXPORTING
i_zfbdt = ls_bseg-zfbdt
i_zbd1t = ls_bseg-zbd1t
i_zbd2t = ls_bseg-zbd2t
i_zbd3t = ls_bseg-zbd3t
i_zbd1p = ls_bseg-zbd1p
i_zbd2p = ls_bseg-zbd2p
i_zterm = ls_bseg-zterm
IMPORTING
e_faedt = ld_due_date.
ENDIF.
" Helper function to populate common fields
MACRO set_common_fields.
ls_event-invoice = iv_bkpf-belnr.
ls_event-sourcesystem = gv_system_id.
ls_event-lastdataupdate = gv_last_update.
ls_event-companycode = iv_bkpf-bukrs.
ls_event-vendorname = ls_lfa1-name1.
ls_event-invoiceduedate = ld_due_date.
SELECT SINGLE wrbtr FROM bseg INTO ls_event-invoiceamount WHERE belnr = iv_bkpf-belnr AND gjahr = iv_bkpf-gjahr AND koart = 'K'.
ENDMACRO.
" 1. Invoice Received
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Received'.
CONCATENATE iv_bkpf-cpudt iv_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
" 2. Invoice Parked (if document was created as parked)
IF iv_bkpf-bstat = 'V'.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Parked'.
CONCATENATE iv_bkpf-cpudt iv_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
" 10. Invoice Posted (For non-parked, same as received. For parked, this needs CDHDR/CDPOS logic not shown for brevity)
IF iv_bkpf-bstat <> 'V'.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Posted'.
CONCATENATE iv_bkpf-budat iv_bkpf-cputm INTO ls_event-eventtime. " Using posting date
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
" 5. & 7. Invoice Blocked / Discrepancy Resolved from Change Docs
DATA: lt_cdhdr TYPE TABLE OF cdhdr, lt_cdpos TYPE TABLE OF cdpos.
DATA(ld_objectkey) = |{ iv_bkpf-bukrs }{ iv_bkpf-belnr }{ iv_bkpf-gjahr }|.
SELECT * FROM cdhdr INTO TABLE lt_cdhdr WHERE objectclas = 'BELEG' AND objectid = ld_objectkey.
IF sy-subrc = 0.
SELECT * FROM cdpos INTO TABLE lt_cdpos FOR ALL ENTRIES IN lt_cdhdr
WHERE changenr = lt_cdhdr-changenr AND tabname = 'BSEG' AND fname = 'ZLSPR'.
LOOP AT lt_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>).
READ TABLE lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>) WITH KEY changenr = <fs_cdpos>-changenr.
IF sy-subrc = 0.
CLEAR ls_event.
set_common_fields.
IF <fs_cdpos>-value_new IS NOT INITIAL AND <fs_cdpos>-value_old IS INITIAL.
ls_event-activityname = 'Invoice Blocked For Payment'.
ELSEIF <fs_cdpos>-value_new IS INITIAL AND <fs_cdpos>-value_old IS NOT INITIAL.
ls_event-activityname = 'Discrepancy Resolved'.
ELSE.
CONTINUE.
ENDIF.
CONCATENATE <fs_cdhdr>-udate <fs_cdhdr>-utime INTO ls_event-eventtime.
ls_event-username = <fs_cdhdr>-username.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDIF.
" 6. 8. 9. Workflow Events (Routed, Approved, Rejected) - Simplified Example
" This requires knowledge of specific workflow templates. Placeholder logic:
" SELECT ... FROM SWW_WI2OBJ ... WHERE INSTID = [Invoice Object]
" SELECT ... FROM SWWWIHEAD ... to get status and times
" 11. & 12. & 14. Payment Proposal, Executed, Cleared
IF ls_bseg-augbl IS NOT INITIAL.
DATA: ls_regup TYPE regup.
SELECT SINGLE * FROM regup INTO ls_regup WHERE vblnr = ls_bseg-belnr.
IF sy-subrc = 0.
DATA(ld_rundate) = ls_regup-laufd.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Proposal Created'.
CONCATENATE ld_rundate '000000' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Executed'.
CONCATENATE ls_bseg-augdt '120000' INTO ls_event-eventtime. " Using clearing date as proxy
APPEND ls_event TO gt_event_log.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Cleared'.
CONCATENATE ls_bseg-augdt '120001' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
" 13. Invoice Due Date Passed (Calculated)
IF ls_bseg-augdt IS NOT INITIAL AND ld_due_date IS NOT INITIAL.
IF ls_bseg-augdt > ld_due_date.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Due Date Passed'.
CONCATENATE ld_due_date '235959' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDIF.
" 15. Invoice Cancelled
IF iv_bkpf-stblg IS NOT INITIAL.
DATA: ls_rev_bkpf TYPE bkpf.
SELECT SINGLE * FROM bkpf INTO ls_rev_bkpf WHERE belnr = iv_bkpf-stblg.
IF sy-subrc = 0.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Cancelled'.
CONCATENATE ls_rev_bkpf-cpudt ls_rev_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = ls_rev_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form PROCESS_MM_INVOICE (Handles MM/Logistics Invoices)
*&---------------------------------------------------------------------*
FORM process_mm_invoice USING iv_rbkp TYPE rbkp.
" This form would be similar to PROCESS_INVOICE, but starts with RBKP.
" It needs to find the corresponding FI document in BKPF via AWKEY.
" The logic for PO/GR Matched would be included here.
" For demonstration, creating placeholder events for MM-specific activities.
DATA: ls_event TYPE ty_event_log.
ls_event-invoice = iv_rbkp-belnr.
ls_event-sourcesystem = gv_system_id.
ls_event-lastdataupdate = gv_last_update.
ls_event-companycode = iv_rbkp-bukrs.
" 1. Invoice Received (MM)
ls_event-activityname = 'Invoice Received'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" 3. Purchase Order Matched (Implicit)
ls_event-activityname = 'Purchase Order Matched'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" 4. Goods Receipt Matched (Implicit)
ls_event-activityname = 'Goods Receipt Matched'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" NOTE: The rest of the events (Block, Pay, etc.) would be found by linking
" RBKP to BKPF and then reusing the logic from PROCESS_INVOICE.
" Link: BKPF-AWKEY = CONCATENATE( RBKP-BELNR, RBKP-GJAHR ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form WRITE_OUTPUT_FILE
*&---------------------------------------------------------------------*
FORM write_output_file.
DATA: lv_string TYPE string.
OPEN DATASET p_fpath FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
MESSAGE 'Error opening file.' TYPE 'E'.
RETURN.
ENDIF.
" Write Header
lv_string = 'Invoice,ActivityName,EventTime,SourceSystem,LastDataUpdate,UserName,CompanyCode,VendorName,InvoiceAmount,PurchaseOrderNumber,InvoiceDueDate'.
TRANSFER lv_string TO p_fpath.
" Write Data
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_event>).
" Create a comma-separated string, handling potential commas in data
CONCATENATE <fs_event>-invoice
<fs_event>-activityname
<fs_event>-eventtime
<fs_event>-sourcesystem
<fs_event>-lastdataupdate
<fs_event>-username
<fs_event>-companycode
<fs_event>-vendorname
<fs_event>-invoiceamount
<fs_event>-purchaseordernumber
<fs_event>-invoiceduedate
INTO lv_string SEPARATED BY ','.
TRANSFER lv_string TO p_fpath.
ENDLOOP.
CLOSE DATASET p_fpath.
WRITE: / 'Extraction complete. File written to:', p_fpath.
ENDFORM. 始めてみませんか?
このテンプレートを使ってプロセスマイニングを始め、買掛金業務の効率を大きく高めましょう。プロセスをさらに最適化し、効率化するための取り組みを今すぐ始められます。
延滞料金を防ぐ:買掛金請求書処理を今すぐ最適化
処理コストを60%削減し、二重支払いを簡単に防止できます。
クレジットカードは不要です。数分で利用を開始できます。