Purchase to Pay - 発注書データテンプレート
SAP S/4HANAPurchase to Pay - 発注書データテンプレート
- 詳細分析に推奨の属性
- プロセス内で追跡すべき主要なアクティビティ
- データ抽出の手順ガイド
購買から支払いまで - 発注属性
| 名前 | 説明 | ||
|---|---|---|---|
| アクティビティ ActivityName | 購買オーダープロセスで発生したビジネスイベントまたはステップの名称。 | ||
| 説明 この属性は、「購買オーダー作成済み」、「購買オーダー承認済み」、または「入荷転記済み」など、購買オーダーのライフサイクル内の特定の行動またはステータス変更を記述します。これらのアクティビティのシーケンスがプロセスフローを形成します。 アクティビティのシーケンスと頻度を分析することは、プロセスマイニングの核です。これにより、実際のプロセスを発見し、設計されたモデルと比較し、ボトルネック(例:「請求書受領済み」後の長い待機時間)を特定し、手戻り(例:繰り返される「購買オーダー変更済み」アクティビティ)を定量化するのに役立ちます。 その重要性 これはプロセスの各ステップを定義し、エンドツーエンドのフローの可視化と分析、バリアント分析、そしてボトルネックの特定を可能にします。 取得元 通常、EKKO/EKPOのステータスフィールドやCDHDR/CDPOSの変更伝票ログなど、テーブルとフィールドの組み合わせから導出され、主要なビジネスマイルストーンを表します。 例 発注作成済み発注承認済み入庫記帳済み請求書受領 | |||
| イベント日時 EventTime | アクティビティの発生時刻を示すタイムスタンプです。 | ||
| 説明 この属性は、プロセス内の各アクティビティの正確な日付と時刻を記録します。プロセスマイニングにおけるすべての時間ベースの分析にとって不可欠です。 イベントタイムは、アクティビティを時系列に並べてプロセスフローを構築するために使用されます。さらに、アクティビティ間のサイクルタイム、待機時間、処理時間など、すべての期間ベースのメトリクスを計算するための基礎となり、これらはパフォーマンス分析とボトルネック特定に不可欠です。 その重要性 このタイムスタンプは、イベントを正しく順序付けし、サイクルタイム、リードタイム、待機時間を含むすべてのパフォーマンスメトリックを計算するために不可欠です。 取得元 作成日(変更の場合はEKKO-AEDAT)や転記日付(入荷の場合はMKPF-BUDAT)など、特定のアクティビティに関連するタイムスタンプフィールド。複数のテーブルからのデータを結合する必要があることがよくあります。 例 2023-04-15T10:00:00Z2023-04-15T14:30:00Z2023-05-01T09:15:00Z | |||
| 購買発注 PurchaseOrderNumber | 購買オーダー(PO)の一意の識別子であり、調達ライフサイクルを追跡するための主要なケースIDとして機能します。 | ||
| 説明 購買オーダー番号は、最初の作成から最終的な入荷と完了まで、すべての関連アクティビティをリンクする中心的な識別子です。プロセスマイニング分析のケース識別子として機能します。 分析において、この番号でイベントをグループ化することで、個々の購買オーダーの旅を再構築できます。これは、サイクルタイムの計算、プロセスバリアントの分析、および単一のオーダーに固有のボトルネックや逸脱の特定に不可欠です。 その重要性 これは、すべての調達イベントを単一のエンドツーエンドプロセスに接続するための不可欠な鍵であり、個々の購買オーダーのライフサイクルを詳細に分析することを可能にします。 取得元 この属性は、SAP S/4HANAのテーブルEKKOのフィールドEBELNで確認できます。 例 450001712345000171244500017125 | |||
| ソースシステム SourceSystem | データが抽出されたソースシステムを特定します。 | ||
| 説明 この属性は、イベントデータの発生元システムを指定します。例えば、「SAP S/4HANA Production」や「SAP ECC」などです。 複数のシステムが混在する環境では、このフィールドはデータリネージ、トラブルシューティング、および異なるソースからのデータが正しく解釈されることを保証するために不可欠です。データのコンテキストを理解するのに役立ち、特定のシステム環境に対する分析をフィルタリングするために使用できます。 その重要性 データの出所に関する重要なコンテキストを提供します。これは、マルチシステム環境でのデータガバナンス、検証、および分析にとって不可欠です。 取得元 これは通常、データ抽出、変換、ロード(ETL)プロセス中に、データセットにその起源を示すために追加される静的な値です。 例 S4H_PROD_100ECC_EU_200S4H_US_300 | |||
| 最終データ更新 LastDataUpdate | データが最後に更新されたか、ソースシステムから抽出された時点のタイムスタンプ。 | ||
| 説明 この属性は、分析されているデータの鮮度を示します。SAP S/4HANAからの最新のデータ抽出の日付と時刻を表示します。 最終データ更新時刻を知ることは、ユーザーが分析のタイムリーさを理解するために不可欠です。リアルタイム情報を見ているのか、特定の時点のスナップショットを見ているのかを知ることで、結果を正しく解釈するのに役立ち、分析に基づいて取られる行動の関連性に影響を与えます。 その重要性 データの適時性についてユーザーに通知し、分析結果のコンテキストと関連性を理解できるようにします。 取得元 これは、データ抽出、変換、ロード(ETL)プロセス中に加えられたメタデータのタイムスタンプです。 例 2024-05-21T02:00:00Z2024-05-20T02:00:00Z2024-05-19T02:00:00Z | |||
| ユーザー UserName | 特定のアクティビティを実行したユーザーの識別子。 | ||
| 説明 この属性は、伝票の作成、変更、または承認を担当したSAPユーザーIDを捕捉します。これにより、システム内で行われたアクションの追跡可能性が提供されます。 ユーザーによる分析は、トレーニングニーズ、作業負荷の分散、および個人のパフォーマンスを特定するのに役立ちます。例えば、特定のユーザーが常に長い承認時間や頻繁な承認後変更に関連しているかどうかを確認するために使用でき、リソース管理やプロセス改善イニシアチブに情報を提供できます。 その重要性 個人またはチームレベルでの説明責任を提供し、パフォーマンス分析を可能にすることで、トレーニング機会やリソースの制約を特定するのに役立ちます。 取得元 この情報は、EKKOのERNAM(作成者)のようなフィールドや、変更伝票テーブル(CDHDR-USERNAME)のユーザーフィールドで確認できます。 例 CB9980000012JSMITHRROE | |||
| 仕入先ID VendorId | 商品またはサービスを提供する仕入先またはベンダーの一意の識別子。 | ||
| 説明 仕入先IDは、購買オーダーを特定の仕入先にリンクする重要なマスタデータです。これは、調達プロセス全体で通信、配送、支払いのために使用されます。 プロセスマイニングでは、この属性により、仕入先別にパフォーマンス分析をセグメント化できます。「仕入先リードタイムパフォーマンス」や「仕入先別返品率」といったダッシュボードに不可欠であり、最も信頼性の高い仕入先や遅延や品質問題を引き起こしている可能性のある仕入先を特定するのに役立ちます。 その重要性 サプライヤー中心の分析を可能にし、パフォーマンスの評価、高パフォーマンスベンダーと低パフォーマンスベンダーの特定、およびサプライチェーンの最適化を支援します。 取得元 この属性は、SAP S/4HANAのテーブルEKKOのフィールドLIFNRにあります。 例 100023100045100088 | |||
| 希望納期 RequestedDeliveryDate | 企業が`ベンダー`に商品またはサービスの配送を要求した日付です。 | ||
| 説明 この属性は、購買オーダーで合意された目標納期を指定します。これは、仕入先の納期遵守パフォーマンスを測定するためのベースラインとして機能します。 プロセスマイニングでは、この日付は実際の入荷日(「入荷転記済み」タイムスタンプ)と比較され、「仕入先納期遵守率」KPIを算出します。この日付からの逸脱を分析することは、仕入先の信頼性を評価し、サプライチェーンのリスクを管理するのに役立ちます。 その重要性 仕入先の納期遵守パフォーマンスを測定するためのベースラインとして機能し、サプライチェーン管理および運用計画における重要なKPIとなります。 取得元 これは、スケジュール行テーブルEKETのフィールドEINDTで確認できます。 例 2023-06-012023-06-152023-07-01 | |||
| 正味合計金額 TotalNetAmount | 税金と運送費を除く、購買オーダーの合計金額。 | ||
| 説明 この属性は、購買オーダーの正味金額を表します。これは、調達取引の規模を示す主要な財務数値です。 この金額は、プロセスパスが異なるかどうかを確認するために、購買オーダーを価値(高価値 vs 低価値)で分類するなど、財務分析にとって重要です。また、より高い財務リスクを伴う可能性のある、またはビジネスへの影響が大きい高価値オーダーに焦点を当てて分析を優先するためにも使用できます。 その重要性 財務ベースの分析を可能にし、購買発注を価値別にセグメント化し、高額支出領域におけるプロセス改善の取り組みを優先順位付けするのに役立ちます。 取得元 この属性は、SAP S/4HANAのテーブルEKKOのフィールドNETWRで確認できます。 例 1500.0025000.50125.75 | |||
| 購買オーダー伝票タイプ DocumentType | 標準購買発注、サービス購買発注、在庫転送オーダーなど、異なる種類の購買発注を区別するための分類です。 | ||
| 説明 伝票タイプは、SAPにおける購買オーダーのプロセスフロー、番号範囲、および項目を制御する主要な設定要素です。これにより、企業は異なるシナリオに合わせて調達プロセスをカスタマイズできます。 伝票タイプによるプロセス分析は、プロセスバリエーションを理解するために不可欠です。例えば、標準的な商品購買オーダーのプロセスは、サービス購買オーダーや在庫転送とは大きく異なる場合があります。この属性により、これらの異なるプロセスフローをフィルタリングおよび比較し、具体的な改善機会を見つけることができます。 その重要性 購買オーダーを分類し、異なる調達プロセスを比較することで、プロセスフローやサイクルタイムの変動を明確にするのに役立ちます。 取得元 この属性は、SAP S/4HANAのテーブルEKKOのフィールドBSARTにあります。 例 NB`FO`UB | |||
| 購買申請 PurchaseRequisitionNumber | 購買オーダーを開始した購買依頼(PR)の識別子。 | ||
| 説明 この属性は、購買オーダーを元の購買依頼にリンクします。直接作成された購買オーダーには、すべてのPRがない場合があります。 このリンクは、最初の要求から始まるエンドツーエンドの調達プロセス全体を分析するために不可欠です。「購買依頼承認時間」のようなKPIをサポートし、先行する承認済み依頼なしに購買オーダーが作成される「マベリックスペンディング」を特定するための基本となります。 その重要性 購買発注を最初の依頼に接続し、エンドツーエンドのプロセス分析と非準拠のマベリック支出の特定を可能にします。 取得元 この属性は、SAP S/4HANAのテーブルEKPO(購買オーダー明細レベル)のフィールドBANFNにあります。 例 1001005110010052 | |||
| `品目コード` MaterialNumber | 調達される特定の品目または商品を示す識別子。 | ||
| 説明 品目コードは、SAPの各品目マスタレコードに割り当てられる一意のコードです。調達、在庫管理、販売など、その品目に関連するすべてのトランザクションに使用されます。 品目コードまたは品目グループによる分析は、コモディティベースの分析を可能にします。これにより、特定の種類の品目の調達プロセスが非効率であるか、リードタイムが長いか、返品が発生しやすいかなどを特定するのに役立ち、カテゴリ管理のための洞察を提供します。 その重要性 品目ベースの分析を可能にし、特定の製品や材料に関連するプロセス問題やサプライヤーパフォーマンス問題を特定するのに役立ちます。 取得元 この属性は、SAP S/4HANAのテーブルEKPOのフィールドMATNRにあります。 例 RM100-100FG210SERV-CONSULT | |||
| `購買発注承認サイクルタイム` PoApprovalCycleTime | 購買オーダーが作成されてから最終承認を受けるまでの算出期間。 | ||
| 説明 このメトリックは、「購買オーダー作成済み」アクティビティと「購買オーダー承認済み」アクティビティ間の経過時間を測定します。各購買オーダーケースについて計算されます。 この属性は、内部承認効率の直接的な尺度を提供します。「購買オーダー承認サイクルタイム」ダッシュボードおよびKPIの主要なメトリックであり、承認プロセスにおける遅延がどこで発生しているかを特定し、加速の機会を正確に指摘するのに役立ちます。 その重要性 内部承認プロセスの効率を直接測定し、調達を遅らせるボトルネックを特定して対処するのに役立ちます。 取得元 各購買発注について、「購買発注承認済み」イベントと「購買発注作成済み」イベントの間の時間差を見つけることによって計算されます。 例 P2D4H30MP0D2H15MP5D | |||
| マベリックスペンディングであるか IsMaverickSpend | 先行する承認済み購買依頼なしに購買発注が作成されたかどうかを示す計算フラグです。 | ||
| 説明 このブールフラグは、データ処理中に導出されます。購買オーダーに関連する購買依頼がない場合、または購買オーダーの作成が標準承認ワークフローを迂回する場合に「true」に設定されます。 この属性は、「マベリックスペンディング識別」ダッシュボードおよび関連KPIを直接サポートします。これにより、非コンプライアンスな購買行動の程度を定量化し、企業が特定の部門やユーザーグループをターゲットにして、調達ポリシーと管理を強化できるようにします。 その重要性 非準拠の購買を直接特定し、プロセスの逸脱を定量化し、財務管理と調達ポリシーの実施を支援します。 取得元 特定の伝票タイプにおける「購買依頼番号」の値の欠如、またはイベントシーケンスの分析に基づいて計算されるフィールドです。 例 truefalse | |||
| 仕入先の納期遵守率 SupplierOnTimeDelivery | 入庫が要求された納期までに転記されたかどうかを示す計算フラグです。 | ||
| 説明 このブール属性は、「入荷転記済み」アクティビティのタイムスタンプと「要求納期」を比較して導出されます。入荷が要求納期以前である場合、「true」とマークされます。 この属性は、「仕入先納期遵守率」KPIを直接サポートします。ユーザーが納期内または遅延配送を簡単にフィルタリングできるようにすることで分析を簡素化し、ベンダーパフォーマンスダッシュボードや仕入先スコアカード作成に不可欠です。 その重要性 サプライヤーの信頼性を直接測定し、納期遵守KPIの基礎を形成し、効果的なベンダーパフォーマンス管理を可能にします。 取得元 「入庫転記済み」アクティビティのタイムスタンプと「要求納期」属性を比較して計算されます。 例 truefalse | |||
| 会社コード CompanyCode | 購買オーダーが作成される法人または会社を示す識別子。 | ||
| 説明 会社コードは、組織内の独立した会計単位を表します。購買オーダーに関連するすべての財務取引は、特定の会社コードに転記されます。 これは、異なる法人間の調達プロセスをフィルタリングおよび比較できる基本的な組織属性です。会社コードによる分析は、プロセス実行における不整合、異なるレベルの効率性、または組織全体のさまざまなコンプライアンス率を明らかにすることができます。 その重要性 法的エンティティ別にプロセス分析をセグメント化し、ビジネスの異なる部分間でのパフォーマンスとコンプライアンスの比較を容易にします。 取得元 この属性は、SAP S/4HANAのテーブルEKKOのフィールドBUKRSにあります。 例 101017102000 | |||
| 品目カテゴリ ItemCategory | 標準、委託、外注、サービスなど、購買発注明細を分類します。 | ||
| 説明 明細カテゴリは、特定の品目またはサービスの調達がどのように管理され、処理されるかを決定します。入荷や請求書照合などの後続ステップに影響を与えます。 この属性は、何が購買されているかに基づいてプロセスバリアントを分析するために重要です。例えば、サービス品目(サービス入力シートが必要)のプロセスは、標準在庫品目とは大きく異なります。明細カテゴリ別に分析することで、これらの違いを説明し、的を絞ったプロセス改善を可能にします。 その重要性 物品、サービス、外注など、さまざまな調達タイプを区別することでプロセスバリエーションを説明します。 取得元 この属性は、SAP S/4HANAのテーブルEKPOのフィールドPSTYPにあります。 例 093 | |||
| 工場 Plant | 商品が納入される、またはサービスが提供される運用施設または場所。 | ||
| 説明 SAPにおいて、プラントは物品が生産、保管されるか、またはサービスが実行される物理的な場所です。これはロジスティクスと計画における重要な要素です。 プラント別にプロセス分析をセグメント化することで、調達プロセスにおける地域的またはサイト固有のバリエーションが明らかになる可能性があります。例えば、特定のプラントでより長い納期が発生しているか、またはより高い返品率があるかを示すことができ、ローカライズされたロジスティクスまたは品質管理の問題を指摘します。 その重要性 場所ベースの分析を可能にし、さまざまな運用サイト、プラント、または倉庫間のプロセスパフォーマンスの違いを浮き彫りにします。 取得元 この属性は、SAP S/4HANAのテーブルEKPOのフィールドWERKSにあります。 例 10101710DE01 | |||
| 手戻り IsRework | 承認後の変更や返品などの手戻りが購買発注で行われたかどうかを示す計算フラグです。 | ||
| 説明 このブール属性は、各購買オーダーのアクティビティのシーケンスを分析して計算されます。「購買オーダー承認済み」イベントの後に「購買オーダー変更済み」イベントが発生した場合、または「商品返品済み」イベントが存在する場合に「true」とマークされます。 このフラグは、「ストレートスルー処理率」KPIの計算を簡素化します。これにより、手動介入または修正が必要だったすべての購買オーダーを簡単にフィルタリングおよび視覚化でき、手戻りのコストと頻度を定量化するのに役立ちます。 その重要性 手戻りのあるケースを特定することでプロセスの非効率性を定量化するのに役立ちます。これは、ストレートスルー処理率の計算や逸脱の根本原因の特定に不可欠です。 取得元 活動のシーケンスに基づいて計算されるフィールドです。ロジックは、「購買発注変更済み」イベントが承認後に続くかどうか、または「返品処理済み」イベントが存在するかどうかをチェックします。 例 truefalse | |||
| 購買グループ PurchasingGroup | 特定の調達活動に責任を持つ購買担当者の特定のグループ。 | ||
| 説明 購買グループとは、特定の購買活動、品目、またはサプライヤーを担当する購買担当者または購買担当者のグループです。彼らはベンダーとの主要な連絡窓口となります。 この属性により、購買組織よりもきめ細かいワークロードとパフォーマンスの分析が可能になります。過負荷になっているチームを特定したり、異なる購買グループの効率を測定したり、マベリック支出のようなプロセスの逸脱を起こしやすいグループを理解したりするために使用できます。 その重要性 購買グループのパフォーマンスを詳細に可視化し、チームレベルでの作業負荷、効率性、プロセス順守状況の分析を可能にします。 取得元 この属性は、SAP S/4HANAのテーブルEKKOのフィールドEKGRPにあります。 例 001002N00 | |||
| 購買組織 PurchasingOrganization | 資材やサービスを調達し、`ベンダー`と交渉する責任を負う`組織単位`です。 | ||
| 説明 購買組織は、調達における主要な組織単位です。企業、会社、またはプラントレベルで構成され、すべての購買活動に責任を負います。 購買組織によるプロセス分析は、異なる調達チームや地域の効率性とパフォーマンスを評価するのに役立ちます。組織単位間の仕入先交渉、プロセスコンプライアンス、または承認遅延の違いを浮き彫りにすることができます。 その重要性 異なる調達部門や地域間のパフォーマンス比較を可能にし、ベストプラクティスや改善領域の特定に役立ちます。 取得元 この属性は、SAP S/4HANAのテーブルEKKOのフィールドEKORGにあります。 例 10101710US01 | |||
購買から支払いまで - 発注活動
| アクティビティ | 説明 | ||
|---|---|---|---|
| 入庫記帳済み | 仕入先からの商品の物理的な受領と、それに対応するシステムへの入力がなされることを表します。これは、購買オーダー履歴を更新する明示的なトランザクションです。 | ||
| その重要性 これは、仕入先のリードタイムを終了させ、内部の請求書照合プロセスを開始する主要なマイルストーンです。納期遵守率を追跡するために不可欠です。 取得元 品目伝票としてMKPF(ヘッダー)テーブルとMSEG(明細)テーブルに記録され、特定の移動タイプ(例:101)で購買オーダー履歴テーブルEKBEにリンクされます。 取得 EKBEを介してリンクされた、品目伝票ヘッダー(MKPF)からの転記日付(BUDAT)。 イベントタイプ explicit | |||
| 発注作成済み | これは、購買依頼を参照してもしなくても作成されうる、公式の購買オーダー伝票の作成を示します。このイベントは、購買オーダー伝票がシステムに最初に保存されたときに明示的に記録されます。 | ||
| その重要性 このアクティビティは、特にマベリック購買分析において、プロセスの代替開始点として機能します。これは、購買オーダーの全体的な処理時間を追跡するための基本的なイベントです。 取得元 購買オーダーヘッダーテーブルEKKOに記録されます。作成日(AEDAT)と時間は、このテーブルに直接保存されます。 取得 購買発注伝票のEKKOテーブルにおける作成タイムスタンプ(AEDAT)です。 イベントタイプ explicit | |||
| 発注承認済み | 購買オーダーが必要な内部承認をすべて受け、仕入先へのリリースが承認されたことを示します。このイベントは、購買オーダーのリリース戦略におけるステータス変更から推測されます。 | ||
| その重要性 これは、承認効率と承認後の手戻りを測定するための重要なマイルストーンです。購買オーダー作成から承認までの時間を分析することで、内部プロセスの遅延が浮き彫りになります。 取得元 EKKOテーブルのリリース区分(FRGKE)から推測されます。タイムスタンプは、このフィールドが「リリース済み」ステータスに更新された時期の変更履歴(CDHDR/CDPOS)を調べることで決定されます。 取得 EKKOテーブルのリリース区分フィールド(FRGKE)に関する変更ログから推測されます。 イベントタイプ inferred | |||
| 発注書完了 | このアクティビティは、購買オーダー明細がロジスティクスの観点から完了と見なされることを示します。「納入完了」および「最終請求書」の両方のインジケーターが設定されたときに推測されます。 | ||
| その重要性 これは、購買オーダーライフサイクル分析の終点として機能します。このイベントまでの時間を測定することで、調達業務のエンドツーエンドのサイクルタイムが提供されます。 取得元 購買発注明細テーブルEKPOのステータスフラグから推測されます。「納入完了」区分(ELIKZ)と「最終請求書」区分(EREKZ)の両方がTrueに設定されたときにイベントが発生します。 取得 EKPOフィールドELIKZとEREKZの両方が完了としてフラグ付けされた際の変更ログから推測されます。 イベントタイプ inferred | |||
| 請求書受領 | 仕入先の請求書がSAPシステムに入力され、対応する購買オーダーにリンクされることを表します。これは、会計伝票を作成する明示的な財務転記です。 | ||
| その重要性 これは、調達プロセスと買掛金プロセスを接続する重要なマイルストーンです。これにより、入荷から請求書処理までの時間を分析することができます。 取得元 会計伝票はテーブルBKPF(ヘッダー)に作成され、その明細はBSEGまたはユニバーサルジャーナルACDOCAにあります。この伝票はテーブルRSEGで購買発注にリンクされます。 取得 会計伝票ヘッダーテーブルBKPFからの伝票入力日付(CPUDT)です。 イベントタイプ explicit | |||
| 購買依頼書作成済み | このアクティビティは、商品またはサービスの正式な要求を示し、調達プロセスを開始します。このイベントは、ユーザーが新しい購買依頼伝票を保存したとき(例:トランザクションME51Nを使用)に明示的に捕捉されます。 | ||
| その重要性 これは、多くの購買オーダーライフサイクルにおける主要な開始点です。このイベントから購買オーダー作成までの時間を分析することで、調達や内部処理における遅延を特定するのに役立ちます。 取得元 EBANテーブル(購買依頼)に記録されます。作成イベントのタイムスタンプは、EBANオブジェクトの変更履歴テーブルCDHDRおよびCDPOSで確認できます。 取得 EBANテーブルに伝票が作成された際に記録されるイベントです。 イベントタイプ explicit | |||
| 購買依頼書承認済み | マネージャーまたは指定された承認者による購買依頼の正式な承認を表します。これは通常、依頼伝票のステータス変更から推測され、購買オーダーへの変換準備が完了したことを示します。 | ||
| その重要性 これは、承認サイクルタイムを追跡し、ボトルネックを特定するための重要なマイルストーンです。ここでの遅延は、購買オーダーが作成され、仕入先に送付されるまでの速度に直接影響します。 取得元 EBANテーブルのリリースステータスフィールド(例:FRGZU - リリース区分)から推測されます。タイムスタンプは、最終リリースステータスが設定された時期を記録する変更伝票(CDHDR/CDPOS)から導出されます。 取得 EBANテーブルのリリースステータスフィールドに関する変更ログ(CDHDR/CDPOS)から推測されます。 イベントタイプ inferred | |||
| サービス確認入力済 | このアクティビティは、購買オーダーで指定されたサービスが実行されたことの確認を示します。これは、サービス入力シートの作成を通じて明示的に捕捉されます。 | ||
| その重要性 サービスベースの調達において、これは入庫に相当します。サービス提供のタイムラインを追跡し、ベンダーへのタイムリーな支払いを可能にする上で重要です。 取得元 サービス入力シートの作成を介して記録され、データはESSR(ヘッダー)テーブルとESLL(明細)テーブルに保存されます。作成日がタイムスタンプとして機能します。 取得 テーブルESSRにおけるサービス明細書伝票の作成日付です。 イベントタイプ explicit | |||
| 発注変更済み | このアクティビティは、購買オーダーの初期作成後に、数量、価格、または納期などの変更が行われたことを示します。これはシステム変更ログに明示的に記録されます。 | ||
| その重要性 変更を追跡すること、特に承認後の変更は、プロセス非効率性、手戻り、および潜在的なコンプライアンス問題を特定するために不可欠です。頻繁な変更は、初期仕様が不十分であることを示唆する可能性があります。 取得元 購買オーダーオブジェクト(EINKBELEG)の変更伝票テーブルCDHDR(ヘッダー)とCDPOS(明細)に記録されます。変更ごとに詳細なログエントリが作成されます。 取得 EKKOまたはEKPOテーブルの主要フィールドの変更について記録されたイベントで、CDHDR/CDPOSに記録されます。 イベントタイプ explicit | |||
| 発注書をベンダーに送付済み | 購買オーダーが、例えばEDI、電子メール、または印刷を介して仕入先に伝達される瞬間を表します。このイベントは、システムの出力管理ログを通じて捕捉されることがよくあります。 | ||
| その重要性 このアクティビティは、仕入先リードタイムの真の開始点です。仕入先がオーダーを受領した瞬間から、そのパフォーマンスを正確に測定するために不可欠です。 取得元 購買伝票のために送信されたメッセージをログに記録する出力管理テーブルNASTから取得されます。関連する出力タイプ(例:EDI、メール)の日付と時刻を使用できます。 取得 NASTテーブル内の購買オーダーに対する最初の成功した出力メッセージのタイムスタンプ。 イベントタイプ inferred | |||
| 請求書支払済み | これは、支払い実行または手動支払いによる仕入先請求書の最終決済を示します。これは消込伝票を作成する明示的な財務取引です。 | ||
| その重要性 技術的には支払いプロセスの一部ですが、このアクティビティを含めることで、調達から支払いまでのサイクル全体を完全に把握できます。支払い条件とパフォーマンスを分析するための鍵となります。 取得元 支払いはBKPF/ACDOCAで消込伝票として記録されます。BSEGまたはACDOCAテーブルの請求書明細の消込日付(AUGDT)が支払いイベントを示します。 取得 BSEGまたはACDOCAにある請求書伝票の消込日付(AUGDT)です。 イベントタイプ explicit | |||
| 購買発注削除済み | 購買オーダー明細または伝票全体のキャンセルまたは論理的な削除を表します。これは、ユーザーが伝票に削除フラグを設定することで捕捉されます。 | ||
| その重要性 このアクティビティは、プロセスの代替終了点であり、失敗またはキャンセルを示します。購買オーダーが削除される理由を分析することで、需要計画や要件定義における問題を明らかにすることができます。 取得元 購買発注ヘッダー(EKKO)または明細(EKPO)テーブルの削除区分フラグ(LOEKZ)から取得されます。タイムスタンプは変更伝票(CDHDR/CDPOS)から導出されます。 取得 削除フラグ(LOEKZ)が設定された際の変更伝票(CDHDR/CDPOS)からのタイムスタンプ。 イベントタイプ explicit | |||
| 返品済み | 以前に受領した物品が、通常は品質問題、損傷、または誤った出荷のためにベンダーに返品されたことを示します。これは明示的な取消入庫として捕捉されます。 | ||
| その重要性 このアクティビティは、手戻りや、仕入先の品質またはオーダーの正確性に関する潜在的な問題を浮き彫りにします。特定の仕入先または品目からの返品頻度が高い場合は、問題があることを示しています。 取得元 特定の返品移動タイプ(例:122)を持つ品目伝票として記録されます。イベントはMKPF/MSEGにログされ、EKBE履歴テーブルの購買オーダーにリンクされます。 取得 EKBE内の返品移動タイプを持つ品目伝票からの転記日付。 イベントタイプ explicit | |||
抽出ガイド
ステップ
- 前提条件とアクセス: SAP S/4HANAシステムでCore Data Services (CDS) ビューをクエリするための適切な権限を持つユーザーがいることを確認してください。アクセスは、SAP HANA Studio、Eclipse用ABAP Development Tools (ADT)、またはSAP HANAデータベースへのSQL接続をサポートするサードパーティのデータ抽出ツールを通じて可能です。
- システム接続詳細の特定: ホスト、インスタンス番号、認証情報を含む、SAP S/4HANAシステムに必要な接続パラメーターを取得してください。
- データベースへの接続: お好みのSQLクライアントを使用して、CDSビューが格納されているSAP S/4HANAデータベースへの接続を確立してください。
- SQLクエリの準備: このドキュメントのクエリセクションに記載されている完全なSQLクエリをSQLエディタにコピーしてください。このクエリは、必要なすべてのアクティビティと属性を抽出するように設計されています。
- フィルタリングパラメーターの設定: クエリ内のプレースホルダーを見つけてください。
_start_dateと_end_dateを分析に望ましい日付範囲(例:'20230101'と'20231231')に置き換えてください。分析したい特定の会社コードを含めるように、poh.CompanyCodeフィルターを変更してください。 - クエリの実行: 変更したSQLクエリをS/4HANAデータベースに対して実行してください。データ量と指定された日付範囲によっては、実行に時間がかかる場合があります。
- 予備結果の確認: クエリが完了したら、SQLクライアントで出力を簡単に確認してください。異なるアクティビティが存在すること、タイムスタンプが正しく入力されていること、ケースID(PurchaseOrderNumber)が一貫していることを確認してください。
- データのエクスポート: SQLツールから完全な結果セットをCSV(カンマ区切り値)ファイルにエクスポートしてください。文字化けを防ぐため、ファイルがUTF-8エンコーディングを使用していることを確認してください。
- アップロードの準備: ProcessMindにアップロードする前に、CSVファイルを開き、列ヘッダーがデータ要件で定義されている属性(PurchaseOrderNumber, ActivityName, EventTimeなど)と正確に一致していることを確認してください。エクスポートツールが列名を変更した場合は、調整してください。
- ProcessMindへのアップロード: 最終化されたCSVファイルをProcessMindプロジェクトにアップロードしてください。インポートプロセス中に、ファイル内の列を対応するケースID、アクティビティ、タイムスタンプフィールドにマッピングしてください。
設定
- 主要なCDSビュー: 抽出ロジックは、標準的でセマンティックに豊かな一連のCDSビューに依存しています。主なビューは以下の通りです。
- I_PurchaseOrderItemAPI01: 購買発注の主要明細データ用。
- I_PurchaseRequisitionItemAPI01: 購買依頼の詳細用。
- I_MaterialDocumentItem: 入庫や返品などの物品移動用。
- I_ServiceEntrySheetAPI01: サービス確認イベント用。
- I_SupplierInvoiceAPI01: 仕入先請求書情報用。
- I_OperationalAcctgDocItem: 支払追跡のために請求書と財務伝票をリンクする用。
- I_ChangeDocument: 購買発注の変更を捕捉する用。
- 日付範囲による絞り込み: パフォーマンスとデータ量を管理するため、日付範囲フィルターを適用することが重要です。クエリは、購買発注作成日(PurchaseOrderDate)に対して
_start_dateおよび_end_dateのプレースホルダーを使用します。推奨される開始範囲は3〜6ヶ月のデータです。 - 組織による絞り込み: 抽出範囲を関連する事業単位に限定するため、クエリは常にCompanyCodeでフィルタリングされるべきです。さらに絞り込むために、PurchaseOrderTypeまたはPurchasingOrganizationに対する追加フィルターをメインのPO_base共通テーブル式に追加できます。
- 前提条件: クエリを実行するユーザーは、上記のすべてのCDSビューに対してSELECT権限が必要です。これらのビューへのアクセスは、通常S/4HANAの特定のビジネスロールまたは分析ロールを通じて付与されます。適切な権限がない場合、クエリは失敗します。
a クエリ例 sql
WITH PO_base AS (
SELECT
poh.PurchaseOrder AS PurchaseOrderNumber,
poi.PurchaseOrderItem AS PurchaseOrderItem,
poh.CompanyCode,
poh.PurchaseOrderType AS DocumentType,
poh.Supplier AS VendorId,
poh.PurchaseOrderDate,
poi.PurchaseRequisition AS PurchaseRequisitionNumber,
poi.NetPriceAmount * poi.OrderQuantity AS TotalNetAmount, -- Note: This is item-level net amount
poh.CreationDate AS POCreationDate,
poh.CreationTime AS POCreationTime,
poh.LastChangeDateTime AS POLastChangeDateTime,
poi.IsDeleted,
poi.DeliveryIsCompleted,
poi.FinalInvoiceIsExpected,
poi.GoodsReceiptIsExpected,
poi.LastGoodsReceiptDate,
poi.LastInvoiceReceiptDate
FROM I_PurchaseOrderAPI01 poh
JOIN I_PurchaseOrderItemAPI01 poi
ON poh.PurchaseOrder = poi.PurchaseOrder
WHERE
poh.PurchaseOrderDate BETWEEN '_start_date' AND '_end_date' -- Placeholder: e.g., '20230101' and '20230630'
AND poh.CompanyCode IN ('[YourCompanyCode]') -- Placeholder: e.g., '1010'
)
-- 1. Purchase Requisition Created
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Created' AS ActivityName,
CAST(CONCAT(pr.CreationDate, 'T', pr.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem, -- Placeholder
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
pr.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate, -- Available in PR, add if needed
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Approved' AS ActivityName,
CAST(CONCAT(pr.PurReqnReleaseDate, 'T', '000000') AS TIMESTAMP) AS EventTime, -- Time is not available in this view
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
WHERE
pr.PurReqnReleaseDate IS NOT NULL
UNION ALL
-- 3. Purchase Order Created
SELECT
po.PurchaseOrderNumber,
'Purchase Order Created' AS ActivityName,
CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
poh.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
UNION ALL
-- 4. Purchase Order Approved
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Approved' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Assuming ReleaseDate reflects final approval
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 5. Purchase Order Sent to Vendor
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Sent to Vendor' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Using ReleaseDate as a proxy for sending time
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 6. Purchase Order Changed
SELECT DISTINCT
ch.OBJECTID AS PurchaseOrderNumber,
'Purchase Order Changed' AS ActivityName,
CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
ch.UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ChangeDocument ch
JOIN PO_base po ON ch.OBJECTID = po.PurchaseOrderNumber
WHERE
ch.ObjectClassName = 'EINKBELEG' -- Object Class for Purchase Documents
AND CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) > CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP)
UNION ALL
-- 7. Goods Receipt Posted
SELECT
po.PurchaseOrderNumber,
'Goods Receipt Posted' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '101'
UNION ALL
-- 8. Services Confirmation Entered
SELECT
po.PurchaseOrderNumber,
'Services Confirmation Entered' AS ActivityName,
CAST(se.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
se.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ServiceEntrySheetAPI01 se
JOIN PO_base po
ON se.PurchaseOrder = po.PurchaseOrderNumber AND se.PurchaseOrderItem = po.PurchaseOrderItem
UNION ALL
-- 9. Goods Returned
SELECT
po.PurchaseOrderNumber,
'Goods Returned' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '122'
UNION ALL
-- 10. Invoice Received
SELECT
po.PurchaseOrderNumber,
'Invoice Received' AS ActivityName,
CAST(inv.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
inv.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
inv.DebitCreditCode = 'H' -- 'H' for Credit (Supplier Invoice)
UNION ALL
-- 11. Invoice Paid
SELECT
po.PurchaseOrderNumber,
'Invoice Paid' AS ActivityName,
CAST(doc.ClearingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
doc.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN I_OperationalAcctgDocItem doc
ON inv.AccountingDocument = doc.AccountingDocument
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
doc.IsCleared = 'X' AND doc.ClearingDate IS NOT NULL
UNION ALL
-- 12. Purchase Order Completed
SELECT
po.PurchaseOrderNumber,
'Purchase Order Completed' AS ActivityName,
CAST(GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
'SYSTEM' AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.DeliveryIsCompleted = 'X'
AND (po.FinalInvoiceIsExpected = 'X' OR po.GoodsReceiptIsExpected = '') -- Logic for completion
AND GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) IS NOT NULL
UNION ALL
-- 13. Purchase Order Deleted
SELECT
po.PurchaseOrderNumber,
'Purchase Order Deleted' AS ActivityName,
CAST(po.POLastChangeDateTime AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- User who set the flag is in change docs
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.IsDeleted = 'X' ステップ
- 前提条件とアクセス: SAP S/4HANAシステムでCore Data Services (CDS) ビューをクエリするための適切な権限を持つユーザーがいることを確認してください。アクセスは、SAP HANA Studio、Eclipse用ABAP Development Tools (ADT)、またはSAP HANAデータベースへのSQL接続をサポートするサードパーティのデータ抽出ツールを通じて可能です。
- システム接続詳細の特定: ホスト、インスタンス番号、認証情報を含む、SAP S/4HANAシステムに必要な接続パラメーターを取得してください。
- データベースへの接続: お好みのSQLクライアントを使用して、CDSビューが格納されているSAP S/4HANAデータベースへの接続を確立してください。
- SQLクエリの準備: このドキュメントのクエリセクションに記載されている完全なSQLクエリをSQLエディタにコピーしてください。このクエリは、必要なすべてのアクティビティと属性を抽出するように設計されています。
- フィルタリングパラメーターの設定: クエリ内のプレースホルダーを見つけてください。
_start_dateと_end_dateを分析に望ましい日付範囲(例:'20230101'と'20231231')に置き換えてください。分析したい特定の会社コードを含めるように、poh.CompanyCodeフィルターを変更してください。 - クエリの実行: 変更したSQLクエリをS/4HANAデータベースに対して実行してください。データ量と指定された日付範囲によっては、実行に時間がかかる場合があります。
- 予備結果の確認: クエリが完了したら、SQLクライアントで出力を簡単に確認してください。異なるアクティビティが存在すること、タイムスタンプが正しく入力されていること、ケースID(PurchaseOrderNumber)が一貫していることを確認してください。
- データのエクスポート: SQLツールから完全な結果セットをCSV(カンマ区切り値)ファイルにエクスポートしてください。文字化けを防ぐため、ファイルがUTF-8エンコーディングを使用していることを確認してください。
- アップロードの準備: ProcessMindにアップロードする前に、CSVファイルを開き、列ヘッダーがデータ要件で定義されている属性(PurchaseOrderNumber, ActivityName, EventTimeなど)と正確に一致していることを確認してください。エクスポートツールが列名を変更した場合は、調整してください。
- ProcessMindへのアップロード: 最終化されたCSVファイルをProcessMindプロジェクトにアップロードしてください。インポートプロセス中に、ファイル内の列を対応するケースID、アクティビティ、タイムスタンプフィールドにマッピングしてください。
設定
- 主要なCDSビュー: 抽出ロジックは、標準的でセマンティックに豊かな一連のCDSビューに依存しています。主なビューは以下の通りです。
- I_PurchaseOrderItemAPI01: 購買発注の主要明細データ用。
- I_PurchaseRequisitionItemAPI01: 購買依頼の詳細用。
- I_MaterialDocumentItem: 入庫や返品などの物品移動用。
- I_ServiceEntrySheetAPI01: サービス確認イベント用。
- I_SupplierInvoiceAPI01: 仕入先請求書情報用。
- I_OperationalAcctgDocItem: 支払追跡のために請求書と財務伝票をリンクする用。
- I_ChangeDocument: 購買発注の変更を捕捉する用。
- 日付範囲による絞り込み: パフォーマンスとデータ量を管理するため、日付範囲フィルターを適用することが重要です。クエリは、購買発注作成日(PurchaseOrderDate)に対して
_start_dateおよび_end_dateのプレースホルダーを使用します。推奨される開始範囲は3〜6ヶ月のデータです。 - 組織による絞り込み: 抽出範囲を関連する事業単位に限定するため、クエリは常にCompanyCodeでフィルタリングされるべきです。さらに絞り込むために、PurchaseOrderTypeまたはPurchasingOrganizationに対する追加フィルターをメインのPO_base共通テーブル式に追加できます。
- 前提条件: クエリを実行するユーザーは、上記のすべてのCDSビューに対してSELECT権限が必要です。これらのビューへのアクセスは、通常S/4HANAの特定のビジネスロールまたは分析ロールを通じて付与されます。適切な権限がない場合、クエリは失敗します。
a クエリ例 sql
WITH PO_base AS (
SELECT
poh.PurchaseOrder AS PurchaseOrderNumber,
poi.PurchaseOrderItem AS PurchaseOrderItem,
poh.CompanyCode,
poh.PurchaseOrderType AS DocumentType,
poh.Supplier AS VendorId,
poh.PurchaseOrderDate,
poi.PurchaseRequisition AS PurchaseRequisitionNumber,
poi.NetPriceAmount * poi.OrderQuantity AS TotalNetAmount, -- Note: This is item-level net amount
poh.CreationDate AS POCreationDate,
poh.CreationTime AS POCreationTime,
poh.LastChangeDateTime AS POLastChangeDateTime,
poi.IsDeleted,
poi.DeliveryIsCompleted,
poi.FinalInvoiceIsExpected,
poi.GoodsReceiptIsExpected,
poi.LastGoodsReceiptDate,
poi.LastInvoiceReceiptDate
FROM I_PurchaseOrderAPI01 poh
JOIN I_PurchaseOrderItemAPI01 poi
ON poh.PurchaseOrder = poi.PurchaseOrder
WHERE
poh.PurchaseOrderDate BETWEEN '_start_date' AND '_end_date' -- Placeholder: e.g., '20230101' and '20230630'
AND poh.CompanyCode IN ('[YourCompanyCode]') -- Placeholder: e.g., '1010'
)
-- 1. Purchase Requisition Created
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Created' AS ActivityName,
CAST(CONCAT(pr.CreationDate, 'T', pr.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem, -- Placeholder
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
pr.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate, -- Available in PR, add if needed
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.PurchaseOrderNumber,
'Purchase Requisition Approved' AS ActivityName,
CAST(CONCAT(pr.PurReqnReleaseDate, 'T', '000000') AS TIMESTAMP) AS EventTime, -- Time is not available in this view
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_PurchaseRequisitionItemAPI01 pr
JOIN PO_base po
ON pr.PurchaseRequisition = po.PurchaseRequisitionNumber AND pr.PurchaseRequisitionItem = po.PurchaseOrderItem
WHERE
pr.PurReqnReleaseDate IS NOT NULL
UNION ALL
-- 3. Purchase Order Created
SELECT
po.PurchaseOrderNumber,
'Purchase Order Created' AS ActivityName,
CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
poh.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
UNION ALL
-- 4. Purchase Order Approved
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Approved' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Assuming ReleaseDate reflects final approval
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- Approver info requires complex joins
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 5. Purchase Order Sent to Vendor
SELECT DISTINCT
po.PurchaseOrderNumber,
'Purchase Order Sent to Vendor' AS ActivityName,
CAST(poh.ReleaseDate AS TIMESTAMP) AS EventTime, -- Using ReleaseDate as a proxy for sending time
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
poi.RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
JOIN I_PurchaseOrderAPI01 poh ON po.PurchaseOrderNumber = poh.PurchaseOrder
JOIN I_PurchaseOrderItemAPI01 poi ON po.PurchaseOrderNumber = poi.PurchaseOrder AND po.PurchaseOrderItem = poi.PurchaseOrderItem
WHERE poh.ReleaseDate IS NOT NULL
UNION ALL
-- 6. Purchase Order Changed
SELECT DISTINCT
ch.OBJECTID AS PurchaseOrderNumber,
'Purchase Order Changed' AS ActivityName,
CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
ch.UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ChangeDocument ch
JOIN PO_base po ON ch.OBJECTID = po.PurchaseOrderNumber
WHERE
ch.ObjectClassName = 'EINKBELEG' -- Object Class for Purchase Documents
AND CAST(CONCAT(ch.ChangeDocumentDate, 'T', ch.ChangeDocumentTime) AS TIMESTAMP) > CAST(CONCAT(po.POCreationDate, 'T', po.POCreationTime) AS TIMESTAMP)
UNION ALL
-- 7. Goods Receipt Posted
SELECT
po.PurchaseOrderNumber,
'Goods Receipt Posted' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '101'
UNION ALL
-- 8. Services Confirmation Entered
SELECT
po.PurchaseOrderNumber,
'Services Confirmation Entered' AS ActivityName,
CAST(se.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
se.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_ServiceEntrySheetAPI01 se
JOIN PO_base po
ON se.PurchaseOrder = po.PurchaseOrderNumber AND se.PurchaseOrderItem = po.PurchaseOrderItem
UNION ALL
-- 9. Goods Returned
SELECT
po.PurchaseOrderNumber,
'Goods Returned' AS ActivityName,
CAST(CONCAT(md.PostingDate, 'T', md.CreationTime) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
md.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_MaterialDocumentItem md
JOIN PO_base po
ON md.PurchaseOrder = po.PurchaseOrderNumber AND md.PurchaseOrderItem = po.PurchaseOrderItem
WHERE
md.GoodsMovementType = '122'
UNION ALL
-- 10. Invoice Received
SELECT
po.PurchaseOrderNumber,
'Invoice Received' AS ActivityName,
CAST(inv.PostingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
inv.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
inv.DebitCreditCode = 'H' -- 'H' for Credit (Supplier Invoice)
UNION ALL
-- 11. Invoice Paid
SELECT
po.PurchaseOrderNumber,
'Invoice Paid' AS ActivityName,
CAST(doc.ClearingDate AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
doc.CreatedByUser AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM I_SupplierInvoiceAPI01 inv
JOIN I_OperationalAcctgDocItem doc
ON inv.AccountingDocument = doc.AccountingDocument
JOIN PO_base po
ON inv.PurchaseOrderReference = po.PurchaseOrderNumber
WHERE
doc.IsCleared = 'X' AND doc.ClearingDate IS NOT NULL
UNION ALL
-- 12. Purchase Order Completed
SELECT
po.PurchaseOrderNumber,
'Purchase Order Completed' AS ActivityName,
CAST(GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
'SYSTEM' AS UserName,
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.DeliveryIsCompleted = 'X'
AND (po.FinalInvoiceIsExpected = 'X' OR po.GoodsReceiptIsExpected = '') -- Logic for completion
AND GREATEST(po.LastGoodsReceiptDate, po.LastInvoiceReceiptDate) IS NOT NULL
UNION ALL
-- 13. Purchase Order Deleted
SELECT
po.PurchaseOrderNumber,
'Purchase Order Deleted' AS ActivityName,
CAST(po.POLastChangeDateTime AS TIMESTAMP) AS EventTime,
'[Your S/4HANA System ID]' AS SourceSystem,
CURRENT_UTCTIMESTAMP AS LastDataUpdate,
po.VendorId,
NULL AS UserName, -- User who set the flag is in change docs
po.TotalNetAmount,
po.PurchaseRequisitionNumber,
NULL AS RequestedDeliveryDate,
po.DocumentType
FROM PO_base po
WHERE
po.IsDeleted = 'X' ステップ
- 仕様と設計: 必須および推奨されるすべての属性を含むイベントログファイルの最終的なデータ構造を定義します。13の必須アクティビティそれぞれについて、データのソースとして使用される特定のSAPテーブル(例:EKKO、EKPO、EKBE、CDHDR、CDPOS、BKPF)を文書化します。
- プログラム作成: SAP GUIで、トランザクションコードSE38またはSE80を使用してABAPエディタに移動します。新しい実行可能プログラム、例えば
Z_PM_PO_EXTRACTを作成します。 - 選択画面の定義: レポートの選択画面をコーディングします。これにより、ユーザーは抽出したいデータをフィルタリングできます。購買発注作成日範囲(P_AEDAT)、会社コード(P_BUKRS)、購買伝票タイプ(P_BSART)のパラメーターを含めます。
- データ宣言: プログラムに必要な内部テーブルとデータ構造を定義します。これには、仕様ステップで定義された構造と一致する最終イベントログ用の内部テーブルが含まれます。
- データ選択ロジックの実装: 13の活動それぞれに対してデータを選択するコアABAPロジックを記述します。これには、関連するSAPテーブルに対する一連の
SELECT文が含まれ、必要に応じて結合されます。変更ベースのイベントについては、変更ログテーブルCDHDRおよびCDPOSから読み取ります。 - データの変換とマッピング: 取得した各レコードについて、SAPテーブルのフィールドを最終イベントログ内部テーブルの対応する列にマッピングします。処理中のイベントに基づいてActivityNameを設定します(例:「購買発注作成済み」)。日付および時刻フィールドをEventTime用の一貫したタイムスタンプ形式に変換します。
- イベントデータの統合: 13の活動タイプすべてを処理した後、すべてのデータが単一の統合された内部テーブルに収集されていることを確認します。このテーブルは、選択された購買発注の完全なイベントログを表します。
- ファイル出力の実装: 最終内部テーブルをファイルに書き出す機能を追加します。推奨されるアプローチは、
cl_gui_frontend_services=>gui_downloadメソッドを使用して、ユーザーがファイルをローカルマシンにCSVとして保存できるようにするか、OPEN DATASETを使用してバックグラウンド処理のためにSAPアプリケーションサーバーに保存することです。 - トランザクションコードの作成(オプション): ビジネスユーザーがプログラムに簡単にアクセスできるように、トランザクションコードSE93を使用して、ABAPプログラムを実行するカスタムトランザクションコード(例:
ZPM_PO_EXTRACT)を作成します。 - バックグラウンドジョブのスケジュール: 大量のデータや自動抽出の場合、トランザクションコードSM36を使用してプログラムをバックグラウンドジョブとして実行するようにスケジュールします。出力ファイルは、プログラムロジックで指定されたアプリケーションサーバーパスに書き込まれます。
設定
- 選択条件: 抽出データを効果的に絞り込むには、選択パラメーターをプログラムに含める必要があります。主要なフィルターは以下の通りです。
- 日付範囲: 購買発注の作成日付(EKKO-AEDAT)の必須日付範囲。データ量とレポートのパフォーマンスを管理するため、3~6ヶ月の期間から始めることを推奨します。
- 会社コード(BUKRS): 複数の法的エンティティを持つ組織において、抽出範囲を絞り込むために不可欠です。
- 購買伝票タイプ(BSART): 標準購買発注、基本契約、在庫転送オーダーなど、特定の購買発注タイプでフィルタリングし、分析に集中できます。
- 変更ログの読み取り: 「購買発注承認済み」や「購買発注変更済み」といった活動の抽出は、SAPの変更ログテーブル(CDHDR、CDPOS)の読み取りに依存します。これはリソースを大量に消費する可能性があります。ABAPロジックは、必要なオブジェクトクラス(EINKBELEG、BANF)とテーブル/フィールドの組み合わせのみを選択するように最適化されるべきです。
- 権限: このレポートを実行するユーザーまたはテクニカルアカウントには、在庫/購買管理(MM)、財務会計(FI)、およびシステム全体のテーブルを含む複数のSAPモジュールにわたるテーブルに対する広範な読み取り権限が必要です。これには、EKKO、EKPO、EBAN、EKBE、BKPF、BSAK、RBKP、NAST、CDHDR、CDPOSなどのテーブルが含まれます。
- バックグラウンド実行: 数ヶ月を超えるデータ抽出、またはトランザクション量の多いシステムでの実行の場合、ダイアログプロセスのタイムアウトを防ぐため、常にプログラムをバックグラウンドで実行してください。
a クエリ例 abap
REPORT z_pm_po_extract.
" ====================================================================
" SELECTION SCREEN
" ====================================================================
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS: s_aedat FOR sy-datum OBLIGATORY.
SELECT-OPTIONS: s_bukrs FOR ekko-bukrs.
SELECT-OPTIONS: s_bsart FOR ekko-bsart.
PARAMETERS: p_sysid TYPE string DEFAULT '[Your SAP System ID]'.
SELECTION-SCREEN END OF BLOCK b1.
" ====================================================================
" DATA DECLARATIONS
" ====================================================================
TYPES: BEGIN OF ty_event_log,
purchaseordernumber TYPE ebeln,
activityname TYPE string,
eventtime TYPE timestamp,
sourcesystem TYPE string,
lastdataupdate TYPE timestamp,
vendorid TYPE lifnr,
username TYPE ernam,
totalnetamount TYPE netwr,
purchaserequisitionnumber TYPE banfn,
requesteddeliverydate TYPE eedat,
documenttype TYPE bsart,
END OF ty_event_log.
DATA: lt_event_log TYPE TABLE OF ty_event_log,
ls_event_log TYPE ty_event_log.
DATA: lt_ekko TYPE TABLE OF ekko,
lt_ekpo TYPE TABLE OF ekpo.
" ====================================================================
" START OF SELECTION
" ====================================================================
START-OF-SELECTION.
" Get current timestamp for LastDataUpdate
GET TIME STAMP FIELD ls_event_log-lastdataupdate.
ls_event_log-sourcesystem = p_sysid.
" --- Initial Data Selection: Purchase Orders in Scope ---
SELECT * FROM ekko INTO TABLE lt_ekko
WHERE aedat IN s_aedat
AND bukrs IN s_bukrs
AND bsart IN s_bsart.
IF lt_ekko IS INITIAL.
MESSAGE 'No Purchase Orders found for the given criteria.' TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
SELECT * FROM ekpo INTO TABLE lt_ekpo
FOR ALL ENTRIES IN lt_ekko
WHERE ebeln = lt_ekko-ebeln.
" --- 1. Purchase Requisition Created ---
SELECT ban.banfn, ban.erdat, ban.erzet, ban.ernam,
ekpo.ebeln, ekpo.netwr, ekpo.eindt, ekpo.bsart, ekpo.lifnr, ekko.bukrs
FROM eban AS ban
INNER JOIN ekpo AS ekpo ON ban.banfn = ekpo.banfn AND ban.bnfpo = ekpo.bnfpo
INNER JOIN ekko AS ekko ON ekpo.ebeln = ekko.ebeln
WHERE ekko.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_pr_created).
LOOP AT lt_pr_created INTO DATA(ls_pr_created).
ls_event_log-purchaseordernumber = ls_pr_created-ebeln.
ls_event_log-activityname = 'Purchase Requisition Created'.
CONVERT DATE ls_pr_created-erdat TIME ls_pr_created-erzet INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-vendorid = ls_pr_created-lifnr.
ls_event_log-username = ls_pr_created-ernam.
ls_event_log-totalnetamount = ls_pr_created-netwr.
ls_event_log-purchaserequisitionnumber = ls_pr_created-banfn.
ls_event_log-requesteddeliverydate = ls_pr_created-eindt.
ls_event_log-documenttype = ls_pr_created-bsart.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 2. Purchase Requisition Approved (via Change Docs on Release Indicator) ---
SELECT h.objectid, h.udate, h.utime, h.username
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.objectclas = p.objectclas AND h.objectid = p.objectid AND h.changenr = p.changenr
INNER JOIN ekpo AS ekpo ON h.objectid = ekpo.banfn
INNER JOIN ekko AS ekko ON ekpo.ebeln = ekko.ebeln
WHERE h.objectclas = 'BANF'
AND p.tabname = 'EBAN'
AND p.fname = 'FRGZU'
AND p.value_new = 'X' "Configure based on your system release indicator for 'Approved'
AND ekko.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_pr_approved).
LOOP AT lt_pr_approved INTO DATA(ls_pr_approved).
SELECT SINGLE ebeln FROM ekpo INTO ls_event_log-purchaseordernumber WHERE banfn = ls_pr_approved-objectid.
ls_event_log-activityname = 'Purchase Requisition Approved'.
CONVERT DATE ls_pr_approved-udate TIME ls_pr_approved-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_pr_approved-username.
" Other attributes can be populated with another SELECT if needed.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 3. Purchase Order Created ---
LOOP AT lt_ekko INTO DATA(ls_ekko_created).
ls_event_log-purchaseordernumber = ls_ekko_created-ebeln.
ls_event_log-activityname = 'Purchase Order Created'.
CONVERT DATE ls_ekko_created-aedat TIME ls_ekko_created-erzet INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-vendorid = ls_ekko_created-lifnr.
ls_event_log-username = ls_ekko_created-ernam.
ls_event_log-totalnetamount = ls_ekko_created-rlwrt.
ls_event_log-purchaserequisitionnumber = ''. "Can be enriched later if needed
ls_event_log-requesteddeliverydate = ''. "Can be enriched from EKPO
ls_event_log-documenttype = ls_ekko_created-bsart.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 4. Purchase Order Approved (via Change Docs on Release Indicator) ---
SELECT h.objectid, h.udate, h.utime, h.username
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.objectclas = p.objectclas AND h.objectid = p.objectid AND h.changenr = p.changenr
WHERE h.objectclas = 'EINKBELEG'
AND p.tabname = 'EKKO'
AND p.fname = 'FRGKE'
AND p.value_new = 'R' "R for Released
AND h.objectid IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_approved).
LOOP AT lt_po_approved INTO DATA(ls_po_approved).
ls_event_log-purchaseordernumber = ls_po_approved-objectid.
ls_event_log-activityname = 'Purchase Order Approved'.
CONVERT DATE ls_po_approved-udate TIME ls_po_approved-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_approved-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 5. Purchase Order Sent to Vendor ---
SELECT n.objky, n.vstat, n.datvr, n.uhrvr, e.ernam
FROM nast AS n
INNER JOIN ekko AS e ON n.objky = e.ebeln
WHERE n.kappl = 'EF' "Application for Purchasing
AND n.kschl = '[Your PO Output Type]' "e.g. NEU
AND n.vstat = '1' "Successfully processed
AND n.objky IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_sent).
LOOP AT lt_po_sent INTO DATA(ls_po_sent).
ls_event_log-purchaseordernumber = ls_po_sent-objky.
ls_event_log-activityname = 'Purchase Order Sent to Vendor'.
CONVERT DATE ls_po_sent-datvr TIME ls_po_sent-uhrvr INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_sent-ernam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 6. Purchase Order Changed ---
SELECT objectid, udate, utime, username FROM cdhdr
WHERE objectclas = 'EINKBELEG'
AND tcode IN ('ME22', 'ME22N')
AND objectid IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_changed).
LOOP AT lt_po_changed INTO DATA(ls_po_changed).
ls_event_log-purchaseordernumber = ls_po_changed-objectid.
ls_event_log-activityname = 'Purchase Order Changed'.
CONVERT DATE ls_po_changed-udate TIME ls_po_changed-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_changed-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 7. Goods Receipt Posted & 9. Goods Returned ---
SELECT e.ebeln, m.budat, m.cpudt, m.cputm, m.usnam, b.shkzg, b.bwart
FROM mkpf AS m
INNER JOIN mseg AS s ON m.mblnr = s.mblnr AND m.mjahr = s.mjahr
INNER JOIN t156 AS t ON s.bwart = t.bwart
INNER JOIN ekbe AS e ON s.ebeln = e.ebeln AND s.ebelp = e.ebelp AND s.mblnr = e.belnr AND s.mjahr = e.gjahr
WHERE e.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
AND e.bwart IN ('101', '102', '122', '123') "GR, GR Reversal, Return
INTO TABLE @DATA(lt_goods_mvmt).
LOOP AT lt_goods_mvmt INTO DATA(ls_goods_mvmt).
ls_event_log-purchaseordernumber = ls_goods_mvmt-ebeln.
IF ls_goods_mvmt-bwart = '101'.
ls_event_log-activityname = 'Goods Receipt Posted'.
ELSE.
ls_event_log-activityname = 'Goods Returned'.
ENDIF.
CONVERT DATE ls_goods_mvmt-cpudt TIME ls_goods_mvmt-cputm INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_goods_mvmt-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 8. Services Confirmation Entered ---
SELECT h.erdat, h.erzeit, h.ernam, l.ebeln
FROM essr AS h
INNER JOIN esll AS l ON h.lblni = l.lblni
WHERE l.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_services).
LOOP AT lt_services INTO DATA(ls_services).
ls_event_log-purchaseordernumber = ls_services-ebeln.
ls_event_log-activityname = 'Services Confirmation Entered'.
CONVERT DATE ls_services-erdat TIME ls_services-erzeit INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_services-ernam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 10. Invoice Received ---
SELECT r.ebeln, r.cpudt, r.cputm, r.usnam
FROM rbkp AS r
WHERE r.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_invoice_rcvd).
LOOP AT lt_invoice_rcvd INTO DATA(ls_invoice_rcvd).
ls_event_log-purchaseordernumber = ls_invoice_rcvd-ebeln.
ls_event_log-activityname = 'Invoice Received'.
CONVERT DATE ls_invoice_rcvd-cpudt TIME ls_invoice_rcvd-cputm INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_invoice_rcvd-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 11. Invoice Paid ---
SELECT b.ebeln, s.augdt, s.augbl, b.usnam
FROM rbkp AS b
INNER JOIN bseg AS e ON b.belnr = e.belnr AND b.gjahr = e.gjahr
INNER JOIN bsak AS s ON e.bukrs = s.bukrs AND e.belnr = s.belnr AND e.gjahr = s.gjahr AND e.buzei = s.buzei
WHERE b.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
AND s.augdt IS NOT NULL
INTO TABLE @DATA(lt_invoice_paid).
LOOP AT lt_invoice_paid INTO DATA(ls_invoice_paid).
ls_event_log-purchaseordernumber = ls_invoice_paid-ebeln.
ls_event_log-activityname = 'Invoice Paid'.
CONVERT DATE ls_invoice_paid-augdt INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_invoice_paid-usnam.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- 12. Purchase Order Completed & 13. Purchase Order Deleted (via Change Docs) ---
SELECT h.objectid, h.udate, h.utime, h.username, p.fname
FROM cdhdr AS h
INNER JOIN cdpos AS p ON h.changenr = p.changenr
INNER JOIN ekpo AS ekpo ON h.objectid = |{ ekpo.ebeln }{ ekpo.ebelp }|
WHERE h.objectclas = 'EINKBELEG'
AND p.tabname = 'EKPO'
AND p.fname IN ('ELIKZ', 'EREKZ', 'LOEKZ')
AND p.value_new = 'X'
AND ekpo.ebeln IN @( VALUE #( FOR ls_ekko IN lt_ekko ( ls_ekko-ebeln ) ) )
INTO TABLE @DATA(lt_po_status_change).
LOOP AT lt_po_status_change INTO DATA(ls_po_status_change).
ls_event_log-purchaseordernumber = substring( val = ls_po_status_change-objectid, off = 0, len = 10 ).
CASE ls_po_status_change-fname.
WHEN 'LOEKZ'.
ls_event_log-activityname = 'Purchase Order Deleted'.
WHEN 'ELIKZ' OR 'EREKZ'.
"This logic may need refinement to check if both are now set.
ls_event_log-activityname = 'Purchase Order Completed'.
ENDCASE.
CONVERT DATE ls_po_status_change-udate TIME ls_po_status_change-utime INTO TIME STAMP ls_event_log-eventtime TIME ZONE sy-zonlo.
ls_event_log-username = ls_po_status_change-username.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
" --- Final Output to CSV ---
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
filename = 'C:\temp\po_event_log.csv'
filetype = 'ASC'
CHANGING
data_tab = lt_event_log.