買掛金請求書処理のデータテンプレート
買掛金請求書処理のデータテンプレート
- 詳細な分析に推奨される属性
- 効果的に追跡すべき主要なプロセスアクティビティ
- データ抽出の手順
買掛金請求書処理の属性
| 名前 | 説明 | ||
|---|---|---|---|
| アクティビティ ActivityName | 請求書処理のライフサイクルで発生した、特定の業務イベントまたはステップの名称です。 | ||
| 説明 アクティビティは、買掛金プロセス内の個別の段階や操作を表します。たとえば、「請求書受領」、「請求書転記済み」、「支払実行済み」などです。プロセスマップを構成する基本要素です。 アクティビティの分析は、プロセスマイニングの中心的な機能です。プロセスの流れを可視化し、一般的な経路を特定し、標準プロセスからの逸脱を検出するとともに、各ステップの頻度と所要時間を測定できます。特定の請求書におけるアクティビティの順序が、その請求書のプロセス上の経路を形成します。 重要な理由 プロセスのステップを定義し、プロセスの流れの可視化と分析、ボトルネックの特定、手戻りループの検出を可能にします。 入手先 伝票ステータスの変更(BKPF-BSTATなど)、変更文書(CDHDR/CDPOSテーブル)、ワークフローログなど、さまざまな情報源から取得します。通常、カスタムの抽出ロジックが必要です。 例 請求書受領請求書承認済み支払実行済み支払ブロック中の請求書 | |||
| イベント時刻 EventTime | アクティビティが発生した正確な日付と時刻です。 | ||
| 説明 イベント時刻は各アクティビティに関連付けられたタイムスタンプであり、請求書に関するイベントの時系列を示します。プロセスの流れを理解し、時間に基づく分析を行うために欠かせないデータです。 分析では、アクティビティを正しい順序に並べ、各ステップ間のサイクルタイムを計算し、待機時間を特定するとともに、期間ごとのプロセスパフォーマンス(前月比など)を分析するために使用します。期間に基づくすべてのKPIの基盤となります。 重要な理由 イベントを時系列に並べ、サイクルタイムや所要時間など、プロセスマイニングの基礎となる時間関連指標を計算するうえで欠かせないタイムスタンプです。 入手先 作成日(BKPF-CPUDT)、転記日(BKPF-BUDAT)、消込日(BSAK-AUGDT)、変更ログのタイムスタンプ(CDHDR-UDATE/UTIME)など、SAPテーブル内のさまざまな日付・時刻フィールドから取得します。 例 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 | 請求書を提出した仕入先の名称です。 | ||
| 説明 仕入先またはベンダーの正式名称を含む属性です。請求書伝票に保存された仕入先番号を介して関連付けられます。 仕入先分析は、仕入先との関係を管理し、特定の仕入先に固有のプロセス上の問題を特定するうえで重要です。「不一致のある請求書を最も多く提出している仕入先はどこか」「特定の戦略的な仕入先に対して、常に期限内に支払えているか」といった問いに答えられます。請求書番号や金額とともに、重複支払の可能性を検出する重要なフィールドでもあります。 重要な理由 仕入先ごとにプロセスパフォーマンスを分析し、問題のある仕入先を特定するとともに、戦略的な仕入先との関係を効果的に管理できます。 入手先 テーブルLFA1の仕入先マスターデータ(NAME1フィールド)から取得します。BKPFまたはRBKPにある仕入先番号(LIFNR)を介して関連付けます。 例 Office Supplies Inc.Global Consulting GroupMachine Parts GmbH | |||
| 会社コード CompanyCode | 請求書が処理される組織単位です。 | ||
| 説明 会社コードは、外部報告用に完全で独立した勘定セットを作成できる最小の組織単位です。買掛金の文脈では、仕入先に対して債務を負う法人を表します。 会社コード単位で分析することで、組織内の異なる法人間でプロセスパフォーマンスを比較できます。どの事業部門が標準プロセスに従っているか、どの部門で効率が低く、サイクルタイムが長く、手戻り率が高いかを特定するのに役立ちます。 重要な理由 異なる法人間でプロセスパフォーマンスを比較し、地域や事業部門に固有の問題と優れた取り組みを特定できます。 入手先 主にFI請求書ではBKPF-BUKRS、MM請求書ではRBKP-BUKRSとして、伝票ヘッダーテーブルにあります。 例 10001710US01DE01 | |||
| 発注番号 PurchaseOrderNumber | 請求書に関連付けられた発注書の一意の識別子です。該当する場合に使用されます。 | ||
| 説明 この属性により、請求書を事前承認済みの発注書(PO)に関連付けられます。PO番号の有無は、3-way matchプロセス(PO・請求書・入庫)の基準になります。 コンプライアンスと効率性を分析するうえで重要な属性です。調達ポリシーの遵守状況を測定する「POなし請求書比率」KPIの計算に使用します。また、「3-Way Matching Performance」ダッシュボードの基盤となり、POに基づく請求書の照合プロセスを分析できます。 重要な理由 3-way matchingの効率性を分析し、POなしで処理された請求書を特定することで、調達ポリシーのコンプライアンスを測定するうえで欠かせません。 入手先 RSEG-EBELN(MM請求書)やBSEG-EBELN(FI請求書)など、請求書明細テーブルに記録されます。 例 45000012344500005678 | |||
| 請求書支払期日 InvoiceDueDate | 仕入先への請求書の支払期限です。 | ||
| 説明 請求書支払期日は、遅延損害金の発生を避け、仕入先との良好な関係を維持するために、仕入先へ支払う期限です。この日付は、請求書の基準日と仕入先との合意済みの支払条件に基づいて計算されます。 「Payment Compliance & Aging」ダッシュボードと「On-Time Payment Rate」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 | |||
| ブロック理由 BlockingReason | 請求書の支払いがブロックされた理由であり、不一致を示します。 | ||
| 説明 3-way matchまたはその他の検証手順で請求書がチェックに失敗すると、支払いがブロックされます。ブロック理由には、数量の不一致、価格差異、入庫情報の欠落など、問題の内容が示されます。 この属性は、「Invoice Discrepancy Rework Analysis」ダッシュボードに欠かせません。さまざまなブロック理由の発生頻度を分析すると、プロセス非効率の根本原因を特定できます。たとえば、「価格差異」が頻発している場合、購買システムのマスターデータに問題がある可能性があります。 重要な理由 請求書の不一致と手戻りの根本原因を直接把握でき、対象を絞ったプロセス改善に取り組めます。 入手先 RSEGなどの請求書明細テーブルにある、SPGR*で始まるフィールド(SPGRP、SPGRQ、SPGRTなど)に保存されます。RBKP_BLOCKEDにも記録される場合があります。 例 価格差異数量差異入庫確認未登録 | |||
| 仕入先請求書番号 VendorInvoiceNumber | 仕入先が請求書に記載した請求書番号です。 | ||
| 説明 仕入先独自の会計システムで付与された参照番号で、紙または電子請求書に記載されています。請求書の受領時に手入力するか、OCRで取得します。 業務運用と分析、特に「Potential Duplicate Invoice Payments」ダッシュボードにとって非常に重要なフィールドです。重複を検出する一般的な方法は、同じ仕入先名、仕入先請求書番号、請求書金額を持つ複数の社内請求書伝票を検索することです。請求書を仕入先とやり取りする際の主要な外部参照番号でもあります。 重要な理由 重複支払いの可能性を検出するための主要なフィールドであり、仕入先との連絡に使う外部参照番号として機能します。 入手先 伝票ヘッダーの「Reference」フィールド、通常はBKPF-XBLNRに保存されます。 例 INV-2023-9876733401120231015-001 | |||
| 割引適用済みかどうか DiscountTaken | 早期支払割引が正常に適用されたかどうかを示すブールフラグです。 | ||
| 説明 請求書の支払い時に現金割引が実際に適用されたかどうかを示す属性です。買掛金プロセスの財務効率を測定する重要な要素です。 このフラグは、「Early Payment Discount Capture Rate」KPIの中核です。支払条件に基づいて割引が可能だった請求書を絞り込み、このフラグを分析することで、どれだけの金額を節約できたか、またどれだけの節約機会を逃したかを正確に計算できます。買掛金プロセスの実績を明確かつ定量的に測定できます。 重要な理由 利用可能な早期支払割引を獲得できたかどうかを直接測定します。これは会社の利益に直接影響します。 入手先 支払伝票の割引金額フィールド(BSEG-SKNTO)が0より大きいかどうかを確認して導出されます。 例 truefalse | |||
| 支払条件 PaymentTerms | 請求書の支払いについて仕入先と合意した条件です。多くの場合、割引の適用条件が含まれます。 | ||
| 説明 支払条件には、支払期日と早期支払割引の条件が定められています。たとえば、「Z001」は「30日以内に支払い、10日以内に支払えば2%割引」を意味する場合があります。 この属性は、「Early Payment Discount Capture Rate」ダッシュボードの基盤です。支払条件を分析すると、割引の対象となるすべての請求書を特定できます。これを実際に適用した割引と比較することで、取り逃した節約機会を把握し、支払プロセスの効率を測定できます。 重要な理由 早期支払割引の機会を分析し、支払プロセスの財務実績を測定するとともに、取り逃した節約を特定するうえで欠かせません。 入手先 仕入先明細のテーブルBSEG-ZTERM、または請求書ヘッダーのRBKP-ZTERMに記録されます。 例 Z0010001NT30 | |||
| 支払遅延かどうか IsLatePayment | 請求書が支払期日を過ぎて支払われたかどうかを示すブールフラグです。 | ||
| 説明 計算によって求められる属性で、請求書が正式な支払期日を過ぎて支払われたかどうかをtrue/falseで示します。「消込日」と「請求書支払期日」を比較して導出します。 このフラグにより、「Payment Compliance & Aging」ダッシュボードと「On-Time Payment Rate」KPIの分析を簡単に行えます。フィルタリングや集計によって、支払遅延件数、期日どおりに支払われた割合、支払遅延率の高い仕入先や会社コードを把握できます。 重要な理由 支払条件の遵守状況を直接測定し、期日どおりの支払いに関するKPIの計算を簡単にするとともに、支払実績の低い領域を特定できます。 入手先 計算属性です。ロジックは次のとおりです:IF ClearingDate > InvoiceDueDate THEN true ELSE false。 例 truefalse | |||
| 消込日 ClearingDate | 支払いが行われ、請求書が未消込明細から消し込まれた日付です。 | ||
| 説明 消込日は、請求書の財務上の決済を示します。「Payment Cleared」アクティビティが発生した日であり、正常に完了する請求書処理の多くで最終ステップにあたります。 この日付を実際の支払日として、請求書支払期日と比較します。そのため、「On-Time Payment Rate」KPIの計算や、支払実績に関する分析に欠かせません。また、請求書のエンドツーエンドのサイクルタイムを計算する際の終点にもなります。 重要な理由 請求書の最終決済を示し、サイクルタイム計算の終点と、期日どおりの支払い分析の基準になります。 入手先 仕入先の消込済み明細を扱うBSAK-AUGDTなどのテーブルに記録されます。 例 2023-10-282023-11-142024-01-09 | |||
| 自動処理かどうか IsAutomated | アクティビティが人のユーザーではなく、システムによって自動的に実行されたかどうかを示すフラグです。 | ||
| 説明 このブール属性により、人が開始したアクティビティと、システムジョブ、ワークフロー、ボットが実行したアクティビティを区別できます。たとえば、自動支払処理やシステムが生成した請求書転記には、自動処理のフラグが設定されます。 この属性を分析すると、買掛金プロセスにおける自動化の度合いを把握できます。自動化施策の成果測定、自動ステップと手動ステップの効率比較、さらなる自動化の機会の特定に利用できます。 重要な理由 プロセスの自動化の度合いを測定し、自動化の効果を分析するとともに、さらなる改善機会を特定できます。 入手先 ユーザー名(「SAP_SYSTEM」や「BATCHUSER」などのシステムユーザーID)または自動ジョブに関連付けられた特定のトランザクションコードに基づいて導出されます。 例 truefalse | |||
| 請求書伝票タイプ InvoiceDocumentType | SAPでの処理方法を制御する、請求書伝票の分類です。 | ||
| 説明 伝票タイプは、会計伝票を分類するSAPの主要な設定要素です。たとえば、「KR」は通常、仕入先請求書に、「RE」はMM請求書に、「KG」は仕入先貸方票に使用されます。このタイプによって、番号範囲や必須フィールドなどが決まります。 プロセス分析では、伝票タイプでフィルタリングすることで、請求書の種類ごとにプロセスフローを比較できます。たとえば、貸方票の承認プロセスは標準的な請求書とは異なる場合があります。「Invoice Approval Routing Variants」ダッシュボードに役立つ情報です。 重要な理由 請求書の種類ごとの処理方法に基づいてプロセスをセグメント化し、処理経路とサイクルタイムの違いを明らかにできます。 入手先 伝票ヘッダーテーブルのフィールドBKPF-BLARTから直接取得します。 例 KRREKG | |||
| 請求書通貨 InvoiceCurrency | 請求書金額に使用される通貨コードです(USD、EURなど)。 | ||
| 説明 請求書金額の通貨を示す属性です。財務上の金額を解釈するために必要な背景情報を提供します。 多国籍の組織では、通貨を考慮せずに請求書を分析すると、誤った結論につながる可能性があります。このフィールドにより、すべての金額を単一の報告通貨に換算する、または通貨別に分析を分けて地域ごとの財務活動を把握するといった処理が可能になります。 重要な理由 請求書金額を正確に財務分析・報告するために必要な背景情報を提供します。特に多国籍の組織で役立ちます。 入手先 主にBKPF-WAERSまたはRBKP-WAERSなどの伝票ヘッダーテーブルに記録されます。 例 USDEURGBPJPY | |||
買掛金請求書処理のアクティビティ
| アクティビティ | 説明 | ||
|---|---|---|---|
| 支払ブロック中の請求書 | システムによって請求書に自動または手動でブロックが設定され、支払できない状態になっています。通常は、価格や数量の不一致、承認の不足などが原因です。 | ||
| 重要な理由 これは問題や手戻りを示す重要な指標です。ブロック理由と期間を分析することで、支払遅延やプロセスの非効率の根本原因を特定できます。 入手先 会計伝票(テーブルBSEG)の仕入先明細にある支払ブロックキー(ZLSPR)フィールドに記録された明示的なステータスです。 取得 BSEG-ZLSPRフィールドにブロック理由が入力された際、変更文書を通じて記録されます。 イベントタイプ explicit | |||
| 支払実行済み | 請求書に対する支払が行われました。支払実行が完了し、支払伝票が作成・転記された時点で取得します。 | ||
| 重要な理由 このアクティビティは、キャッシュフロー分析と「期限内支払率」KPIの測定に欠かせません。日付を請求書の支払期限と比較して分析します。 入手先 請求書を消し込む支払伝票の転記日から取得します。支払伝票番号は、請求書明細(BSEG)の消込伝票フィールド(AUGBL)に関連付けられています。 取得 請求書明細を消し込む支払伝票の転記日(BUDAT)を特定します。 イベントタイプ explicit | |||
| 支払消込済み | このアクティビティは、補助元帳上で支払と請求書が照合され、請求書が最終的にクローズされたことを示します。プロセスが完了した状態です。 | ||
| 重要な理由 プロセスの確定した終了点となるこのアクティビティは、正確なエンドツーエンドのサイクルタイム計算に欠かせません。債務が決済されたことを確認できます。 入手先 請求書伝票の仕入先明細(テーブルBSEG)で、消込日(AUGDT)フィールドに値が入力されたことによって明示的に記録されます。 取得 請求書明細から消込日(BSEG-AUGDT)を使用します。 イベントタイプ 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 | |||
| 承認に回付された請求書 | 請求書が業務ルールに基づく必要な承認を受けるため、ワークフローに送信されました。承認サブプロセスの開始を示します。 | ||
| 重要な理由 このアクティビティは、「請求書承認時間の平均」KPIの測定と、承認のボトルネック分析の起点となります。 入手先 請求書オブジェクト(BUS2081など)に関連付けられたワークフローインスタンスの開始を記録するSAP Business Workflowログ(SWW*テーブル)から取得できます。 取得 請求書伝票に関連付けられたSAPワークフローログ(SWW_WIHEADなど)から、ワークフロー開始イベントを抽出します。 イベントタイプ explicit | |||
| 支払提案作成 | 請求書が支払実行(F110など)の一部として支払提案に含まれました。支払実行の最終処理を待つ、支払予定の状態です。 | ||
| 重要な理由 このアクティビティは、未決済債務から支払準備中の項目へ移行したことを示し、支払業務の効率分析に役立ちます。 入手先 このイベントは、支払実行データテーブル、具体的にはREGUP(支払プログラムの処理済み項目)とREGUH(ヘッダー)に明示的に記録されます。 取得 REGUHで特定された支払実行について、請求書がテーブルREGUPに登録された時点を特定します。 イベントタイプ explicit | |||
| 発注書照合済み | このアクティビティは、請求書が対応する発注書との照合に成功したことを示します。調達に基づく請求書では、3方向照合における重要なステップです。 | ||
| 重要な理由 このアクティビティを分析することで、照合プロセスの効率を測定できます。また、「3方向照合パフォーマンス」や「発注書なし請求書比率」KPIの基礎となります。 入手先 テーブルBSEGまたはACDOCAの請求書明細に、有効な発注書番号(EBELN)と明細番号(EBELP)が含まれている場合に推定します。 取得 請求書伝票の作成時に、発注書参照(BSEG-EBELN)が存在することから推定します。 イベントタイプ inferred | |||
| 請求書の支払期限超過 | 請求書の正味支払期限を過ぎても、支払による消込が行われていないことを示す計算イベントです。支払遅延または期限超過の状態を意味します。 | ||
| 重要な理由 「支払コンプライアンスと滞留期間」ダッシュボードに欠かせないアクティビティです。期限超過請求書を早期に特定・管理し、支払遅延の根本原因を分析できます。 入手先 SAPに明示的なイベントとして記録されるものではありません。システムの現在日付と正味支払期限(BSEG-ZFBDTまたは基準日と支払条件から算出)を比較して計算します。 取得 イベントのタイムスタンプが請求書の正味支払期限を超えたときに発生する計算イベントです。 イベントタイプ calculated | |||
| 請求書保留 | 請求書がシステムに入力されたものの、総勘定元帳にはまだ転記されていない状態を示します。不完全な伝票を後の処理や承認のために保存する、意図的なステップである場合が多くあります。 | ||
| 重要な理由 保留中の請求書を追跡することで、正式な転記処理が始まる前の遅延を特定し、データの完全性や初期検証に関する問題を明らかにできます。 入手先 このステータスは、会計伝票ヘッダー(BKPF-BSTAT)の伝票ステータスが「V」(保留)に設定されていることから推定します。イベントは、ステータスが設定された時点で発生します。 取得 テーブルBKPFの変更文書を特定し、BSTATフィールドが「V」(Vor-erfasst/事前入力済み)に設定されていることを確認します。 イベントタイプ inferred | |||
| 請求書却下 | 承認者が承認ワークフロー中に請求書を却下しました。通常、この操作によって請求書は修正または確認のため処理担当者に差し戻されます。 | ||
| 重要な理由 却下を追跡することで、承認プロセス内の手戻りループを明らかにし、ポリシーへの適合性や請求書コードの誤りに関する問題を把握できます。 入手先 請求書に関連付けられたSAP Business Workflowログ内の、特定の結果イベントとして取得します。 取得 SAPワークフローログから「却下」ステータスのイベントを抽出します。 イベントタイプ explicit | |||
抽出ガイド
ステップ
- 前提条件とアクセス権限:CDS Viewが格納されているSAP S/4HANAデータベーススキーマ(通常はSAPABAP1など)への読み取り権限を持つユーザーを用意します。また、SAP HANAデータベースに接続できるSQLクライアントツール(SAP HANA Studio、DBeaverなど)が必要です。
- 主要なCDS Viewを確認:この抽出で使用する主なCDS Viewは、I_JournalEntry、I_JournalEntryItem、I_SupplierInvoiceAPI01、I_ChangeDocument、I_WorkflowStatusDetails、I_PaymentProposalItemです。それぞれの主要フィールドを確認しておきます。
- クエリの対象範囲を定義:SQLクライアントを開き、SAP HANAデータベースに接続します。完全なクエリを実行する前に、抽出対象を定義します。ソースシステム識別子、請求書の期間(CreationDateTime)、対象の会社コードを正しく設定します。
- メインクエリを準備:クエリセクションに記載された完全なSQLクエリをSQLクライアントにコピーします。このクエリでは、まずCommon Table Expressions(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への直接クエリは、リソースを大量に消費する場合があります。提供されているクエリでは、最初に請求書を絞り込むことで負荷の軽減を図っています。非常に大規模なデータセットでは、業務時間外に抽出するか、日付範囲を小さなバッチに分けて実行することを検討してください。
a サンプルクエリ 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実行ツールで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つのタイムゾーンに統一します。日付しか存在しない場合は、文書化した既定の時刻要素を使用し、その制約をデータ辞書に記録します。
- **イベントの意味付け:**各アクティビティを個別の行として抽出します。複数のアクティビティを1件の請求書レコードにまとめないでください。また、ProcessMindが照合、承認、支払期日、消込イベントを導出することを前提にしないでください。
- **支払期日イベント:**設定した評価タイムスタンプより支払期日が前で、その時点までに消込イベントが存在しない請求書についてのみ、Invoice Due Date Passedを生成します。この計算には[Evaluation timestamp]を使用します。
- **性能:**初期の期間と会社範囲を限定し、インデックスまたはパーティションに関連する項目で絞り込み、不要な広範囲の項目取得を避け、承認済みのレポート実行時間帯に実行します。本番クエリが合意した実行時間を超える場合は、ソースの一部をステージングすることを検討します。
- **更新戦略:**LastDataUpdateには抽出の実行タイムスタンプを設定します。増分ロードでは、関連するソース変更タイムスタンプに基づくウォーターマークを保持し、遅れて反映される更新や取消を取得できるよう、ルックバック期間を設けます。
- **前提条件:**必要なデータベース権限、承認済みの本番アクセス、システムのUniversal Journal設定に関する知識、設定された保留伝票、購買、入庫、ワークフロー、支払、消込、取消ソースへのアクセス、該当するSAPライセンスまたはガバナンス承認が必要です。
a サンプルクエリ 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という名前を付けます。説明的なタイトルを入力し、アプリケーションを「Financial Accounting」に設定します。
- 選択画面を定義:プログラム内で、PARAMETERSおよびSELECT-OPTIONSキーワードを使用して選択画面を定義します。ユーザーが抽出期間(請求書作成日)、対象の会社コード(BUKRS)、関連する請求書伝票タイプ(BLART)を指定できるようにします。アプリケーションサーバー上の出力ファイルパス用パラメーターも追加します。
- データを宣言:すべての必須属性および推奨属性を含む最終イベントログ形式(例:TY_EVENT_LOG)に一致する内部テーブル構造を定義します。BKPF、BSEG、RBKP、RSEG、CDHDR、CDPOS、REGUHなど、各SAPソーステーブルから選択したデータを保持する内部テーブルを宣言します。
- 主要データを選択:ユーザーが選択画面で指定した条件に基づき、RBKP(ロジスティクス請求書)およびBKPF(財務請求書)から請求書の主要セットを選択して、抽出ロジックを開始します。後続のデータ検索に使用する主要請求書キーを内部テーブルに保存します。
- アクティビティを順番に抽出:主要セットの各請求書について一連の選択処理を実行し、各業務アクティビティのタイムスタンプと詳細を検索します。たとえば、支払ブロックの変更にはCDHDRとCDPOS、支払実行データにはREGUHとREGUP、取消伝票の詳細にはBKPFを照会します。見つかった各アクティビティについて、最終イベントログテーブルに新しいレコードを追加します。
- 計算イベントのロジック:テーブル項目に直接保存されていないアクティビティについて、ABAPロジックを実装します。Invoice Due Date Passedイベントでは、請求書の支払期日(BSEG-ZFBDT+支払条件)と消込日(BSEG-AUGDT)を使用します。消込日が支払期日より後の場合、支払期日をタイムスタンプとして新しいイベントレコードを作成します。
- データを変換して補完:各アクティビティのデータを収集しながら、必要な属性をすべて設定します。これには、LFA1から仕入先名を検索すること、日付と時刻を1つのタイムスタンプ文字列に変換すること(CONCATENATE...INTO...)、SourceSystemの値を設定することが含まれます。
- 出力ファイルを生成:すべての請求書と対応するアクティビティを処理して最終内部テーブルに収集したら、OPEN DATASET、LOOP AT ... TRANSFER、CLOSE DATASETステートメントを使用して、選択画面で指定したアプリケーションサーバーのパスにファイルを書き込みます。
- ダウンロードしてアップロードの準備:トランザクションコードCG3Yを使用して、生成したファイルをアプリケーションサーバーからローカルマシンにダウンロードします。ファイルがUTF-8エンコードのCSV形式で保存されていることを確認します。Process Miningツールにアップロードする前に、列見出しが必須属性(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アプリケーションサーバー上のファイルパスとファイル名を指定するPARAMETERです(例:/tmp/ディレクトリ)。ダウンロード前に、ここへファイルを書き込みます。
- 前提条件:レポートを実行するユーザーには、FI、CO、MMテーブル(BKPF、BSEG、RBKP、RSEG、LFA1)、変更文書テーブル(CDHDR、CDPOS)、ワークフローテーブルを読み取る権限が必要です。また、アプリケーションサーバーにファイルを書き込むには、権限オブジェクトS_DATASETが必要です。
a サンプルクエリ 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%削減し、重複支払いを簡単に防止します。
クレジットカードは不要です。数分で始められます。