Your Inventory Management Data Template
Your Inventory Management Data Template
- Recommended attributes to collect
- Key activities to track for process discovery
- Extraction guidance tailored for SAP S/4HANA
Inventory Management Attributes
| Name | Description | ||
|---|---|---|---|
| Event Time EventTime | The precise date and time when the inventory activity was recorded in the system. | ||
| Description Event Time is the timestamp that records exactly when an activity occurred. This data point is essential for ordering events chronologically to reconstruct the process flow for each inventory batch. It serves as the basis for all time-based process mining analysis. The accuracy of the Event Time is critical for calculating key performance indicators such as cycle times, lead times, and durations. It enables the analysis of process performance over different time periods, helps identify when bottlenecks occur, and provides the factual basis for understanding process delays, like the time a batch spends in quality inspection before being released. Why it matters This timestamp orders events chronologically and is the foundation for all duration and performance calculations. Where to get This is typically a combination of the posting date (MKPF-BUDAT) and entry time (MKPF-CPUTM) from the material document header table MKPF. Examples 2023-10-26T09:00:00Z2023-11-15T14:35:10Z2024-01-05T23:15:00Z | |||
| Inventory Batch/Lot InventoryBatchLot | The unique identifier for a specific quantity of a product, serving as the case ID for tracking its lifecycle. | ||
| Description The Inventory Batch or Lot number is the primary case identifier that groups all activities related to a specific, distinct quantity of a product. This enables a complete chronological view of a stock quantity's journey, from its initial receipt into the warehouse, through various internal movements and status changes, to its eventual issue for a sale, production, or disposal. In process analysis, this attribute is fundamental. It allows you to trace the end-to-end flow for each batch, measure cycle times accurately, identify process variations, and understand how different batches are handled. Analyzing processes at the batch level is crucial for industries where traceability, quality control, and expiration date management are critical, such as pharmaceuticals, food and beverage, and chemicals. Why it matters This is the core identifier that connects all related inventory events into a single case, making end-to-end process analysis possible. Where to get This is typically the Batch Number, found in SAP tables like MCHA (Batch Master) or MCH1 (Batches) in the field CHARG. Examples B001-A452023L202405-XYZ789456123BATCH-05-24 | |||
| Activity ActivityName | The name of the business event that occurred at a specific point in the inventory management process. | ||
| Description The Activity attribute describes a single step or event within the inventory lifecycle of a batch. These events represent key business actions such as receiving goods, moving stock, performing a quality inspection, or issuing materials. Each activity is a record of something that happened to the inventory batch at a specific point in time. Analyzing activities is the foundation of process mining. It allows for the visualization of the process flow, identification of frequent and rare pathways, detection of bottlenecks where activities are delayed, and analysis of rework loops. By understanding the sequence and frequency of activities like 'Stock Scrapped' or 'Quality Inspection', businesses can pinpoint areas for process improvement and operational efficiency. Why it matters It defines the steps in the process, enabling the visualization and analysis of the inventory lifecycle. Where to get This is a derived attribute, often mapped from SAP Movement Types (MSEG-BWART) or Transaction Codes (MKPF-TCODE2) to user-friendly names. Examples Goods Receipt PostedPut-Away Transfer PostedGoods Issue for Delivery PostedStock Scrapped | |||
| Material Number MaterialNumber | The unique identifier for the product or material being managed. | ||
| Description The Material Number, often referred to as a SKU (Stock Keeping Unit), is the unique code assigned to a specific product. It is a fundamental master data element in inventory management, used to track quantities, values, and movements of goods. In process mining, analyzing by Material Number allows for a product-centric view of inventory processes. It helps answer questions such as which products have the longest quality inspection times, which are scrapped most often, or which have the highest volume of internal transfers. This segmentation is crucial for identifying product-specific issues and optimizing inventory strategies for different types of goods. Why it matters It allows for the segmentation of analysis by product, revealing patterns and issues specific to certain items. Where to get Found in the material document item table MSEG, field MATNR. Master data is in table MARA. Examples RM-1001FG-2050-B100-400-A | |||
| Movement Reason Code MovementReasonCode | A code that specifies the reason for an inventory movement. | ||
| Description The Reason for Movement code provides additional context for why a goods movement was carried out. It is often used to explain unplanned movements, such as inventory adjustments, returns, or scrapping. This attribute is extremely valuable for root cause analysis. For the 'Manual Inventory Adjustment Drivers' dashboard, analyzing by reason code can reveal why discrepancies occur, such as damage, theft, or data entry errors. This insight helps businesses address the underlying problems rather than just correcting the symptoms. Why it matters It explains the 'why' behind unplanned inventory movements, enabling targeted root cause analysis. Where to get Found in the material document item table MSEG, field GRUND (Reason for Movement). Examples 00010005102 | |||
| Movement Type MovementType | A three-digit key in SAP that controls how a goods movement is posted. | ||
| Description The Movement Type is a critical control key in SAP Inventory Management that determines the characteristics of a material movement. It specifies which accounts are updated, how the screen layout appears for the transaction, and what quantity or value fields are updated. For example, '101' is for goods receipt, '311' is for a transfer posting, and '551' is for scrapping. This attribute is often the source for deriving the user-friendly 'Activity' name. Analyzing processes by Movement Type allows for a detailed, technical view of how inventory is flowing. It is essential for validating the accuracy of the process map and for identifying specific types of transactions that may be causing bottlenecks or deviations. Why it matters It provides a precise, technical classification of each inventory event, which is crucial for deriving activities and for detailed analysis. Where to get Found in the material document item table MSEG, field BWART (Movement Type). Examples 101311261551601 | |||
| Plant Plant | The organizational unit representing a facility where inventory is located, such as a factory or distribution center. | ||
| Description A Plant is a central organizational unit in SAP that can represent a production facility, a central storage location, or a corporate headquarters. All inventory is physically or logically located within a Plant. Analyzing by Plant is fundamental for comparing process performance across different physical locations. It helps answer questions like, 'Which plant has the longest put-away cycle time?' or 'Is the inventory discrepancy rate higher in Plant A than in Plant B?'. This geographical or organizational segmentation is key to identifying location-specific issues and sharing best practices across the organization. Why it matters It enables comparison of inventory processes and performance across different company locations. Where to get Found in the material document item table MSEG, field WERKS (Plant). Examples 10001710DE01US01 | |||
| Quantity Quantity | The quantity of the material involved in the inventory movement. | ||
| Description This attribute represents the amount of material that was moved, received, issued, or adjusted in a given activity. It is recorded in the base unit of measure for the material. Analyzing the quantity is crucial for understanding the scale and impact of inventory processes. It allows for the creation of dashboards that visualize the volume of goods being handled, such as 'Goods Issue Throughput by SKU'. It is also used to calculate KPIs like the 'Stock Scrapped/Disposed Ratio', providing a quantitative dimension to the process analysis that goes beyond just counting events. Why it matters It quantifies the volume of material in each activity, enabling analysis of throughput, scrap volume, and adjustment impact. Where to get Found in the material document item table MSEG, field MENGE (Quantity). Examples 10012.55000-10 | |||
| Storage Location StorageLocation | A specific location within a Plant where stock is physically stored. | ||
| Description A Storage Location is an organizational unit that allows for the differentiation of material stocks within a Plant. For example, a plant might have separate storage locations for raw materials, finished goods, and quality inspection stock. This attribute provides a more granular level of location detail than the Plant. It is used in analysis to understand movements between different stock areas, such as the lead time for transfers from the receiving area to the main warehouse. Analyzing storage utilization and movement frequency by storage location helps optimize warehouse layout and internal logistics. Why it matters It provides a granular view of stock location within a plant, helping to analyze internal movements and storage efficiency. Where to get Found in the material document item table MSEG, field LGORT (Storage Location). Examples 0001RM01FG01QI01 | |||
| User Name UserName | The user ID of the person who executed the transaction in SAP. | ||
| Description This attribute captures the SAP user ID of the employee who posted the document or executed the activity. It provides traceability by showing who is responsible for specific actions within the inventory management process. Analyzing by user is essential for understanding performance, compliance, and training needs. For instance, the 'Manual Inventory Adjustment Drivers' dashboard uses this attribute to see who performs the most adjustments. It can help identify users who may require additional training, highlight unauthorized activities, or recognize top performers. Why it matters It provides accountability and helps identify user-specific behaviors, training needs, or compliance issues. Where to get Found in the material document header table MKPF, field USNAM (User Name). Examples JSMITHMBROWNWAREHOUSE_OPS | |||
| Expiration Date ExpirationDate | The date on which the batch of material expires and is no longer usable. | ||
| Description The Shelf Life Expiration Date (SLED) is a critical piece of master data for perishable or time-sensitive goods. It is managed at the batch level and dictates when a product can no longer be sold or consumed. This attribute is essential for the 'Obsolete & Expired Stock Analysis' dashboard. By analyzing activities in the context of the expiration date, businesses can identify batches at risk of expiring and take proactive measures. It helps in measuring the effectiveness of inventory rotation policies like First-Expired-First-Out (FEFO) and in quantifying losses due to scrapped expired stock. Why it matters It enables the analysis of obsolete and expired stock, helping to minimize waste and financial loss. Where to get Found in the batch master table MCH1 or MCHA, field VFDAT (Shelf Life Expiration Date). Examples 2024-12-312025-06-302024-09-01 | |||
| Last Data Update LastDataUpdate | The timestamp indicating when the data for this record was last refreshed from the source system. | ||
| Description This attribute records the date and time of the most recent data extraction or update from the source system. It provides crucial metadata about the freshness of the information being analyzed. This helps users understand if they are looking at near real-time data or a snapshot from a previous period. In any analysis, knowing the data's timeliness is key to making relevant and accurate conclusions. This field allows analysts and business users to confirm the data's currency and is often displayed in dashboards to provide context to the presented insights. Why it matters It informs users about the freshness of the data, ensuring that analyses are based on up-to-date information. Where to get This timestamp is generated and added during the data extraction, transformation, and loading (ETL) process. Examples 2024-05-21T08:00:00Z2024-05-20T08:00:00Z | |||
| Material Document Number MaterialDocumentNumber | The unique number identifying the material document that records the goods movement. | ||
| Description When a goods movement is posted in SAP, the system generates a material document as proof of the movement. This attribute is the unique identifier for that document. A single material document can contain multiple items or activities. In process mining, the Material Document Number is a key transactional identifier that can be used to group related events that were posted together. It is also essential for auditing and for drilling down from the process analysis into the source system to investigate specific transactions. Why it matters It serves as a transactional key for auditing and allows grouping of activities that were executed together. Where to get Found in tables MKPF (header) and MSEG (item), field MBLNR (Number of Material Document). Examples 490000123450000056784900002345 | |||
| Order Fulfillment Cycle Time OrderFulfillmentCycleTime | The end-to-end duration from when picking starts to when goods are issued for delivery. | ||
| Description This is a calculated metric that measures the total time from the 'Picking Initiated' activity to the 'Goods Issue for Delivery Posted' activity. It represents the total time taken by the warehouse to prepare and ship a customer order once the process begins. This attribute is a direct measure of the 'Order Fulfillment Cycle Time' KPI. Analyzing this duration helps businesses understand their responsiveness to customer demand. It can be broken down by product, warehouse, or customer to identify where delays are occurring in the pick, pack, and ship process, directly impacting customer satisfaction and logistical efficiency. Why it matters It measures the speed and efficiency of the warehouse outflow process, which is a key factor in customer satisfaction. Where to get This is a calculated attribute, derived by computing the time difference between the 'Picking Initiated' and 'Goods Issue for Delivery Posted' events for each batch. Examples 7200144003600 | |||
| Quality Inspection Cycle Time QualityInspectionCycleTime | The duration a batch spends in quality inspection before being released. | ||
| Description This calculated metric measures the time elapsed between the 'Stock Posted to Quality Inspection' activity and the 'Quality Inspection Stock Released' activity for a given inventory batch. It represents the time that goods are unavailable for use due to quality control processes. This attribute directly supports the 'Quality Inspection Cycle Time' KPI and dashboard. By calculating and analyzing this duration, businesses can identify bottlenecks in the quality process, compare performance across different materials or plants, and find opportunities to streamline inspections to improve overall stock availability and reduce lead times. Why it matters It quantifies delays caused by quality control, highlighting opportunities to increase stock availability and process speed. Where to get This is a calculated field, derived by finding the time difference between the timestamps of the start and end activities of the quality inspection phase. Examples 2880086400172800 | |||
| Source System SourceSystem | Identifies the source system from which the data was extracted. | ||
| Description This attribute specifies the system of record where the inventory management data originated. In this context, it would be the specific SAP S/4HANA instance. This information is crucial in environments where data might be pulled from multiple ERPs, warehouse management systems, or legacy platforms. While it may seem static in a single-system analysis, it becomes vital when merging data from different sources to create a holistic process view. It helps in data governance, troubleshooting data extraction issues, and ensuring data lineage is clear. Why it matters It provides context about the data's origin, which is essential for data governance and multi-system analysis. Where to get This is typically a hardcoded value set during the data transformation process to identify the specific SAP S/4HANA instance. Examples S4H_PROD_100SAP_S4_FINANCES4HANA_GLOBAL | |||
| Stock Type StockType | Indicates the status of the inventory, such as unrestricted, in quality inspection, or blocked. | ||
| Description Stock Type categorizes inventory based on its usability. The main types are unrestricted-use stock (freely available), quality inspection stock (awaiting quality checks), and blocked stock (not available for use). Goods movements often involve changing the stock type. Tracking changes in stock type is fundamental to understanding the inventory availability process. It directly supports activities like 'Stock Posted to Quality Inspection' and 'Stock Status Changed to Blocked'. Analyzing the time spent in each stock type, especially 'quality inspection', is key for identifying delays that impact the availability of goods for sale or production. Why it matters It tracks the usability status of inventory, which is crucial for analyzing delays in quality inspection and stock availability. Where to get Found in the material document item table MSEG, field INSMK (Stock Type). Examples Unrestricted-UseQuality InspectionBlocked Stock | |||
| Storage Bin StorageBin | The most granular storage unit in a warehouse where materials are physically located. | ||
| Description A Storage Bin represents a specific coordinate in a warehouse, such as a rack location. This level of detail is typically used when SAP Warehouse Management (WM) or Extended Warehouse Management (EWM) is implemented. For the 'Warehouse Storage Utilization' dashboard, this attribute is critical. It allows for analysis of how effectively warehouse space is being used, identifies potential congestion hot spots, and can reveal inefficient put-away or picking paths. Analyzing movements between storage bins helps to optimize warehouse layout and reduce travel time for operators. Why it matters It provides the most granular location data, enabling analysis of warehouse space utilization and operational efficiency. Where to get If using WM, this can be found in transfer order tables like LTAK/LTAP. For inventory documents, it might be in MSEG-LGPBE. Consult SAP S/4HANA documentation. Examples A-01-01-AB-05-10-CRCV-AREA-01 | |||
| Unit Of Measure UnitOfMeasure | The unit in which the quantity of the material is measured (e.g., pieces, kilograms). | ||
| Description The Unit of Measure specifies the unit for the 'Quantity' attribute. Common examples include pieces (PC), kilograms (KG), liters (L), or boxes (BOX). This provides essential context for the quantity field. While often used as a simple descriptor, this attribute is important for ensuring data quality and for analyses where different units need to be converted to a common standard. For example, to accurately calculate the total value of scrapped inventory, quantities in different units must be understood and potentially converted. Why it matters It provides essential context to the 'Quantity' attribute, ensuring accurate interpretation of material volumes. Where to get Found in the material document item table MSEG, field MEINS (Base Unit of Measure). Examples PCKGEAM | |||
Inventory Management Activities
| Activity | Description | ||
|---|---|---|---|
| Goods Issue for Delivery Posted | Records the final step of the outbound process, where ownership of the batch is transferred to a customer or carrier. This is an explicit transaction that reduces inventory and posts to accounting. | ||
| Why it matters This is a key completion event for the order fulfillment process. It is crucial for measuring on-time delivery and calculating the overall order fulfillment cycle time. Where to get Recorded in the MATDOC table. Identified by the Movement Type (BWART) for goods issue to a sales order delivery, typically 601. Capture Captured from material documents in MATDOC with movement type 601. Event type explicit | |||
| Goods Issue for Production Posted | Represents the consumption of an inventory batch by a production or process order. This transaction reduces inventory and allocates the material cost to the manufacturing order. | ||
| Why it matters This is a primary consumption event, marking the end of the inventory lifecycle for components. It's critical for analyzing material availability for production and consumption patterns. Where to get Recorded in the MATDOC table. Identified by Movement Types (BWART) for goods issue to an order, such as 261. Capture Captured from material documents in MATDOC with movement type 261. Event type explicit | |||
| Goods Receipt Posted | Marks the initial entry of an inventory batch into the warehouse, typically from a supplier or production. This event is explicitly captured in SAP S/4HANA as a material document is created upon receiving the goods. | ||
| Why it matters This is the primary start event for the inventory lifecycle. Analyzing the time from this activity to others, like put-away, is crucial for measuring receiving dock efficiency. Where to get Recorded in the MATDOC table. Identified by specific Movement Types (BWART), such as 101 for Purchase Order receipts or 103 for GR into blocked stock. Capture Captured from material documents in MATDOC with corresponding goods receipt movement types. Event type explicit | |||
| Inventory Adjustment Posted | Records a change in stock quantity resulting from a physical inventory count or other discrepancy. This event explicitly adjusts the book inventory to match the physical count. | ||
| Why it matters These adjustments are critical for maintaining inventory accuracy. A high frequency of adjustments indicates underlying problems in stock handling, security, or data entry. Where to get Recorded in the MATDOC table. Identified by physical inventory Movement Types (BWART), such as 701 (inventory gain) or 702 (inventory loss). Capture Captured from material documents in MATDOC with physical inventory adjustment movement types (e.g., 701, 702). Event type explicit | |||
| Put-Away Transfer Posted | Represents the physical movement of the batch from a receiving or staging area to its final storage location or bin. This is recorded as a transfer posting material document in SAP. | ||
| Why it matters Completes the inbound receiving process. The time taken to complete this activity, known as put-away time, is a critical KPI for warehouse efficiency. Where to get Recorded in the MATDOC table as a transfer posting, often between storage locations (e.g., Movement Type 311). The specific movement can vary based on warehouse structure. Capture Identified by transfer posting documents in MATDOC that move stock from an interim/receiving SLoc to a final storage SLoc. Event type explicit | |||
| Quality Inspection Stock Released | Indicates that a batch has passed quality inspection and is now available for use or put-away. This is recorded as an explicit transfer posting from quality stock to another stock type, like unrestricted use. | ||
| Why it matters This milestone marks the completion of the quality process, making the inventory available. Delays here can cause significant downstream issues in production or fulfillment. Where to get Recorded in the MATDOC table as a transfer posting. Typically identified by Movement Type (BWART) 321, moving stock from 'Quality Inspection' to 'Unrestricted-use'. Capture Captured from material documents in MATDOC with movement type 321. Event type explicit | |||
| Stock Scrapped | Marks the final disposal of an inventory batch, removing it from inventory records permanently. This typically occurs for expired, damaged, or obsolete stock. | ||
| Why it matters This is an end event representing a financial loss. Analyzing scrapping events helps identify issues with inventory aging, handling procedures, or demand forecasting. Where to get Recorded in the MATDOC table. Identified by Movement Types (BWART) for scrapping, such as 551 (from unrestricted), 553 (from QI), or 555 (from blocked). Capture Captured from material documents in MATDOC with scrapping movement types (e.g., 551). Event type explicit | |||
| Batch Status Changed | Reflects a change in the batch master record, such as changing its status from 'Unrestricted' to 'Restricted'. This is not a material movement but a change to master data, which is logged. | ||
| Why it matters Changes in batch status directly impact its usability in sales or production. Analyzing these changes can reveal issues with expiring stock or quality control that don't involve physical movement. Where to get Inferred from change logs for the Batch Master tables (MCH1, MCHA). The CDHDR and CDPOS tables track changes to the batch status field (MCH1-ZUSTD). Capture Derived from change documents in CDHDR/CDPOS for the status field in the batch master record (MCH1-ZUSTD). Event type inferred | |||
| Internal Stock Transfer Posted | Captures the movement of an inventory batch between different storage locations or bins within the same plant. This is an explicit transaction creating a material document. | ||
| Why it matters Tracking internal transfers helps analyze warehouse operational efficiency, identify unnecessary movements, and measure the lead time for stock replenishment between locations. Where to get Recorded in the MATDOC table. Commonly identified by Movement Type (BWART) 311 for storage location to storage location transfers. Capture Captured from material documents in MATDOC with movement types for internal stock movements (e.g., 311). Event type explicit | |||
| Picking Initiated | Marks the start of the order fulfillment process where a warehouse task is created to pick a batch from its storage bin. This is often captured when a Transfer Order or Warehouse Task is created. | ||
| Why it matters This activity is the trigger for the picking process. Analyzing the time from this event to picking completion helps measure warehouse operator efficiency and identify delays. Where to get This is typically not in MATDOC. In systems with Warehouse Management (WM/EWM), this is inferred from the creation timestamp of a Transfer Order (LTAK table) or Warehouse Task. Capture Inferred from creation record of a Transfer Order (in WM) or Warehouse Task (in EWM) linked to the material batch. Event type inferred | |||
| Sales Return Received | Captures the return of a previously issued batch from a customer back into the warehouse. This is an explicit transaction that increases inventory. | ||
| Why it matters Tracking returns is essential for understanding product quality issues and customer dissatisfaction. The process for handling and dispositioning returns can also be a source of inefficiency. Where to get Recorded in the MATDOC table. Identified by Movement Types (BWART) for sales returns, such as 651 (to unrestricted) or 653 (to quality inspection). Capture Captured from material documents in MATDOC with sales return movement types (e.g., 651, 653). Event type explicit | |||
| Stock Posted to Quality Inspection | Represents the movement of a received batch into a quality inspection holding status, making it unavailable for use until cleared. This is an explicit transaction in SAP, changing the stock type of the batch. | ||
| Why it matters This activity initiates the quality inspection process. The duration between this and the release from QI is a key metric for understanding quality-related delays. Where to get Recorded in the MATDOC table. This can be a goods receipt movement (e.g., 101) with the Stock Type (INSMK) set to 'Q' (Quality Inspection) or a transfer posting (e.g., 322). Capture Identified by material documents in MATDOC that place inventory into the 'Quality Inspection' stock type. Event type explicit | |||
| Stock Status Changed to Blocked | Represents a change in the batch's status, making it unavailable for issue, often due to damage, hold requests, or other reasons. This is an explicit transfer posting in SAP. | ||
| Why it matters Highlights interruptions in inventory availability. A high frequency of blocking events can indicate issues with handling, storage conditions, or supplier quality. Where to get Recorded in the MATDOC table as a transfer posting. Commonly uses Movement Type (BWART) 344 to move stock from 'Blocked' to 'Unrestricted', and 343 to move from 'Unrestricted' to 'Blocked'. This activity is for 343. Capture Identified by material documents in MATDOC with movement type 343. Event type explicit | |||
| Stock Status Changed to Unrestricted | Represents a change in the batch's status, releasing it from a blocked or quality hold and making it available for use. This is recorded as an explicit transfer posting. | ||
| Why it matters This activity marks the resolution of an inventory hold. The time stock spends in a blocked state can be analyzed to improve resolution processes. Where to get Recorded in the MATDOC table as a transfer posting. Movement Type (BWART) 344 moves stock from 'Blocked' to 'Unrestricted-use'. Capture Identified by material documents in MATDOC with movement type 344. Event type explicit | |||
Extraction Guides
Steps
- Establish System Access: Ensure you have a user with the necessary authorizations to query Core Data Services (CDS) views in the SAP S/4HANA system. This typically requires access granted by a system administrator.
- Choose a SQL Client: Select a SQL client tool that can connect to the SAP HANA database. Common choices include SAP HANA Studio, SAP HANA Database Explorer, or third party tools like DBeaver.
- Configure Database Connection: Using your SQL client, create a new database connection. You will need the HANA database host name, port number (typically 3
15), and your database user credentials. - Prepare the SQL Query: Copy the complete SQL query provided in the 'query' section of this document into your SQL client's editor.
- Set Query Parameters: Locate the placeholder values within the query. You must replace
I_MaterialDocumentItem.PostingDate BETWEEN 'YYYYMMDD' AND 'YYYYMMDD'with your desired date range, for example,BETWEEN '20230101' AND '20230630'. Also, update any company or plant specific filters likeMaterialDocumentItem.Plant IN ('Plant1', 'Plant2')to match your organizational structure. - Execute the Query: Run the modified SQL query against the S/4HANA database. The execution time will vary depending on the date range and the volume of inventory data in your system.
- Review the Data: Once the query finishes, review the results in your SQL client to ensure they appear correct and complete. Check for the presence of different activities and the population of key attributes.
- Export the Event Log: Export the entire result set from your SQL client to a CSV file. Ensure the export settings use UTF-8 encoding to prevent character issues.
- Prepare for Upload: Name the columns in the CSV file exactly as aliased in the query, for example,
InventoryBatchLot,ActivityName,EventTime, and so on. This file is now ready to be uploaded to a process mining tool.
Configuration
- Authorizations: The user running the query needs
SELECTpermissions on the following CDS views:I_MaterialDocumentItem,I_BatchChangeDocument, andI_WarehouseTask. Access to the underlying database schema where these views reside is also required. - Date Range Filtering: It is critical to apply a date range filter to the
PostingDate,ChangeDocumentCreationDate, orWarehouseTaskCreationDatefields. A typical range for analysis is 3 to 12 months. Querying for multiple years can cause significant performance issues. - Organizational Filters: For better performance and targeted analysis, add
WHEREclauses to filter byPlantorCompanyCode. This reduces the data volume and focuses the extraction on relevant parts of the business. - Data Volume: Be aware that inventory management systems generate a high volume of data. A wide date range can result in millions of rows, potentially impacting both the source system during extraction and the performance of your client tool.
- Extended Warehouse Management (EWM): The 'Picking Initiated' activity relies on the
I_WarehouseTaskCDS view, which is only populated if you use SAP Extended Warehouse Management. If your organization uses the older Warehouse Management (WM) module or only Inventory Management (IM), this specific activity will not be extracted.
a Sample Query sql
SELECT
mat_doc.Batch AS "InventoryBatchLot",
CASE
WHEN mat_doc.MovementType = '101' AND mat_doc.InventoryStockType = '2' THEN 'Stock Posted to Quality Inspection'
WHEN mat_doc.MovementType = '101' THEN 'Goods Receipt Posted'
WHEN mat_doc.MovementType = '321' THEN 'Quality Inspection Stock Released'
WHEN mat_doc.MovementType = '311' THEN 'Internal Stock Transfer Posted'
WHEN mat_doc.MovementType = '344' THEN 'Stock Status Changed to Blocked'
WHEN mat_doc.MovementType IN ('343', '322') THEN 'Stock Status Changed to Unrestricted'
WHEN mat_doc.MovementType IN ('701', '702') THEN 'Inventory Adjustment Posted'
WHEN mat_doc.MovementType = '601' THEN 'Goods Issue for Delivery Posted'
WHEN mat_doc.MovementType = '261' THEN 'Goods Issue for Production Posted'
WHEN mat_doc.MovementType IN ('651', '653') THEN 'Sales Return Received'
WHEN mat_doc.MovementType = '551' THEN 'Stock Scrapped'
WHEN mat_doc.MovementType = '313' THEN 'Put-Away Transfer Posted' -- Example for two-step transfers
ELSE 'Unknown Material Movement'
END AS "ActivityName",
TO_TIMESTAMP(mat_doc.PostingDate || LPAD(mat_doc.CreationTime, 6, '0'), 'YYYYMMDDHH24MISS') AS "EventTime",
mat_doc.Material AS "MaterialNumber",
mat_doc.CreatedByUser AS "UserName",
mat_doc.MovementType AS "MovementType",
mat_doc.Plant AS "Plant",
mat_doc.StorageLocation AS "StorageLocation",
mat_doc.QuantityInEntryUnit AS "Quantity",
mat_doc.ReasonForMovement AS "MovementReasonCode"
FROM
I_MaterialDocumentItem AS mat_doc
WHERE
mat_doc.Batch IS NOT NULL AND mat_doc.Batch <> ''
AND mat_doc.PostingDate BETWEEN '20230101' AND '20231231' -- Placeholder: Set your date range
-- AND mat_doc.Plant IN ('Plant1', 'Plant2') -- Placeholder: Add filters for relevant plants
UNION ALL
SELECT
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 3) AS "InventoryBatchLot",
'Batch Status Changed' AS "ActivityName",
change_doc.ChangeDocumentCreationDateTime AS "EventTime",
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 1) AS "MaterialNumber",
change_doc.ChangedByUser AS "UserName",
NULL AS "MovementType",
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 2) AS "Plant",
NULL AS "StorageLocation",
NULL AS "Quantity",
NULL AS "MovementReasonCode"
FROM
I_BatchChangeDocument AS change_doc
WHERE
change_doc.ChangeDocumentTable = 'MCHA' AND change_doc.ChangeDocumentTableFieldName = 'ZUSTD'
AND TO_VARCHAR(change_doc.ChangeDocumentCreationDate) BETWEEN '20230101' AND '20231231' -- Placeholder: Set your date range
UNION ALL
SELECT
wh_task.Batch AS "InventoryBatchLot",
'Picking Initiated' AS "ActivityName",
wh_task.WarehouseTaskCreationDateTime AS "EventTime",
wh_task.Product AS "MaterialNumber",
wh_task.CreatedByUser AS "UserName",
NULL AS "MovementType",
wh_task.Plant AS "Plant",
wh_task.SourceStorageLocation AS "StorageLocation",
wh_task.TargetQuantity AS "Quantity",
NULL AS "MovementReasonCode"
FROM
I_WarehouseTask AS wh_task
WHERE
wh_task.Batch IS NOT NULL AND wh_task.Batch <> ''
AND wh_task.WarehouseProcessType IN ('P210', 'P220') -- Placeholder: Adjust process types based on your picking configuration
AND TO_VARCHAR(wh_task.WarehouseTaskCreationDate) BETWEEN '20230101' AND '20231231'; -- Placeholder: Set your date range Steps
- Establish System Access: Ensure you have a user with the necessary authorizations to query Core Data Services (CDS) views in the SAP S/4HANA system. This typically requires access granted by a system administrator.
- Choose a SQL Client: Select a SQL client tool that can connect to the SAP HANA database. Common choices include SAP HANA Studio, SAP HANA Database Explorer, or third party tools like DBeaver.
- Configure Database Connection: Using your SQL client, create a new database connection. You will need the HANA database host name, port number (typically 3
15), and your database user credentials. - Prepare the SQL Query: Copy the complete SQL query provided in the 'query' section of this document into your SQL client's editor.
- Set Query Parameters: Locate the placeholder values within the query. You must replace
I_MaterialDocumentItem.PostingDate BETWEEN 'YYYYMMDD' AND 'YYYYMMDD'with your desired date range, for example,BETWEEN '20230101' AND '20230630'. Also, update any company or plant specific filters likeMaterialDocumentItem.Plant IN ('Plant1', 'Plant2')to match your organizational structure. - Execute the Query: Run the modified SQL query against the S/4HANA database. The execution time will vary depending on the date range and the volume of inventory data in your system.
- Review the Data: Once the query finishes, review the results in your SQL client to ensure they appear correct and complete. Check for the presence of different activities and the population of key attributes.
- Export the Event Log: Export the entire result set from your SQL client to a CSV file. Ensure the export settings use UTF-8 encoding to prevent character issues.
- Prepare for Upload: Name the columns in the CSV file exactly as aliased in the query, for example,
InventoryBatchLot,ActivityName,EventTime, and so on. This file is now ready to be uploaded to a process mining tool.
Configuration
- Authorizations: The user running the query needs
SELECTpermissions on the following CDS views:I_MaterialDocumentItem,I_BatchChangeDocument, andI_WarehouseTask. Access to the underlying database schema where these views reside is also required. - Date Range Filtering: It is critical to apply a date range filter to the
PostingDate,ChangeDocumentCreationDate, orWarehouseTaskCreationDatefields. A typical range for analysis is 3 to 12 months. Querying for multiple years can cause significant performance issues. - Organizational Filters: For better performance and targeted analysis, add
WHEREclauses to filter byPlantorCompanyCode. This reduces the data volume and focuses the extraction on relevant parts of the business. - Data Volume: Be aware that inventory management systems generate a high volume of data. A wide date range can result in millions of rows, potentially impacting both the source system during extraction and the performance of your client tool.
- Extended Warehouse Management (EWM): The 'Picking Initiated' activity relies on the
I_WarehouseTaskCDS view, which is only populated if you use SAP Extended Warehouse Management. If your organization uses the older Warehouse Management (WM) module or only Inventory Management (IM), this specific activity will not be extracted.
a Sample Query sql
SELECT
mat_doc.Batch AS "InventoryBatchLot",
CASE
WHEN mat_doc.MovementType = '101' AND mat_doc.InventoryStockType = '2' THEN 'Stock Posted to Quality Inspection'
WHEN mat_doc.MovementType = '101' THEN 'Goods Receipt Posted'
WHEN mat_doc.MovementType = '321' THEN 'Quality Inspection Stock Released'
WHEN mat_doc.MovementType = '311' THEN 'Internal Stock Transfer Posted'
WHEN mat_doc.MovementType = '344' THEN 'Stock Status Changed to Blocked'
WHEN mat_doc.MovementType IN ('343', '322') THEN 'Stock Status Changed to Unrestricted'
WHEN mat_doc.MovementType IN ('701', '702') THEN 'Inventory Adjustment Posted'
WHEN mat_doc.MovementType = '601' THEN 'Goods Issue for Delivery Posted'
WHEN mat_doc.MovementType = '261' THEN 'Goods Issue for Production Posted'
WHEN mat_doc.MovementType IN ('651', '653') THEN 'Sales Return Received'
WHEN mat_doc.MovementType = '551' THEN 'Stock Scrapped'
WHEN mat_doc.MovementType = '313' THEN 'Put-Away Transfer Posted' -- Example for two-step transfers
ELSE 'Unknown Material Movement'
END AS "ActivityName",
TO_TIMESTAMP(mat_doc.PostingDate || LPAD(mat_doc.CreationTime, 6, '0'), 'YYYYMMDDHH24MISS') AS "EventTime",
mat_doc.Material AS "MaterialNumber",
mat_doc.CreatedByUser AS "UserName",
mat_doc.MovementType AS "MovementType",
mat_doc.Plant AS "Plant",
mat_doc.StorageLocation AS "StorageLocation",
mat_doc.QuantityInEntryUnit AS "Quantity",
mat_doc.ReasonForMovement AS "MovementReasonCode"
FROM
I_MaterialDocumentItem AS mat_doc
WHERE
mat_doc.Batch IS NOT NULL AND mat_doc.Batch <> ''
AND mat_doc.PostingDate BETWEEN '20230101' AND '20231231' -- Placeholder: Set your date range
-- AND mat_doc.Plant IN ('Plant1', 'Plant2') -- Placeholder: Add filters for relevant plants
UNION ALL
SELECT
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 3) AS "InventoryBatchLot",
'Batch Status Changed' AS "ActivityName",
change_doc.ChangeDocumentCreationDateTime AS "EventTime",
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 1) AS "MaterialNumber",
change_doc.ChangedByUser AS "UserName",
NULL AS "MovementType",
SPLIT_PART(change_doc.ChangeableObjectDescription, '/', 2) AS "Plant",
NULL AS "StorageLocation",
NULL AS "Quantity",
NULL AS "MovementReasonCode"
FROM
I_BatchChangeDocument AS change_doc
WHERE
change_doc.ChangeDocumentTable = 'MCHA' AND change_doc.ChangeDocumentTableFieldName = 'ZUSTD'
AND TO_VARCHAR(change_doc.ChangeDocumentCreationDate) BETWEEN '20230101' AND '20231231' -- Placeholder: Set your date range
UNION ALL
SELECT
wh_task.Batch AS "InventoryBatchLot",
'Picking Initiated' AS "ActivityName",
wh_task.WarehouseTaskCreationDateTime AS "EventTime",
wh_task.Product AS "MaterialNumber",
wh_task.CreatedByUser AS "UserName",
NULL AS "MovementType",
wh_task.Plant AS "Plant",
wh_task.SourceStorageLocation AS "StorageLocation",
wh_task.TargetQuantity AS "Quantity",
NULL AS "MovementReasonCode"
FROM
I_WarehouseTask AS wh_task
WHERE
wh_task.Batch IS NOT NULL AND wh_task.Batch <> ''
AND wh_task.WarehouseProcessType IN ('P210', 'P220') -- Placeholder: Adjust process types based on your picking configuration
AND TO_VARCHAR(wh_task.WarehouseTaskCreationDate) BETWEEN '20230101' AND '20231231'; -- Placeholder: Set your date range Steps
- Access the ABAP Editor: Log into your SAP S/4HANA system. Open the ABAP Editor using the transaction code
SE38. - Create a New Program: Enter a name for the new program in the 'Program' field, for example,
Z_PM_INVENTORY_EXTRACT, and click the 'Create' button. Provide a descriptive title, set the 'Type' to 'Executable Program', and save it to a package. - Define Program Parameters: In the program editor, define the selection screen that will serve as the user interface for the extraction. This allows users to specify parameters like the date range and plant for the data extraction.
- Implement the Extraction Logic: Copy the complete ABAP code provided in the 'Query' section and paste it into the ABAP Editor. This code is designed to select data for all 14 required inventory activities from various SAP tables.
- Understand the Core Logic: The program works by selecting data for each distinct inventory activity from its source tables, such as
MKPFandMSEGfor material movements orCDHDRandCDPOSfor master data changes. Each selection is then combined usingUNION ALLinto a single internal table that represents the event log. - Configure the File Output: The final part of the code handles writing the consolidated data from the internal table to a file. It uses the
OPEN DATASETstatement to create a file on the SAP application server. You must specify a valid server path where the SAP system user has write permissions. - Execute the Program: Save and activate the ABAP program (Ctrl+F3). Execute it by pressing F8. On the selection screen, enter the desired date range and any other relevant filters, like Plant or Company Code.
- Run as a Background Job: For large data volumes, it is critical to execute the program as a background job to avoid session timeouts. From the execution screen (F8), go to the menu
Program -> Execute in Background. Schedule the job to run during off-peak hours. - Retrieve the Output File: Once the job is complete, locate the output file on the SAP application server. Use transaction code
AL11to browse the server directories and find your file. Use transactionCG3Yto download the file from the application server to your local computer. - Prepare for Upload: Open the downloaded file in a text editor or spreadsheet software. Ensure it is formatted as a CSV file with a header row, using a comma as the delimiter and double quotes as the text qualifier. Verify the column names match the requirements before uploading to the process mining tool.
Configuration
- Posting Date Range: This is the most critical parameter. We recommend extracting data in manageable batches, such as 3-6 months at a time, to ensure good performance and avoid system timeouts.
- Plant Filter: It is highly advisable to filter by one or more specific Plants (
WERKS). Running the extraction for all plants simultaneously can be extremely resource-intensive. - Company Code Filter: You can add an optional filter for Company Code (
BUKRS) to further limit the data scope if your organization operates with multiple company codes within the same system. - Application Server File Path: The ABAP program requires a pre-defined, valid directory path on the SAP application server. Ensure the SAP system user (
SY-UNAME) has the necessary OS-level permissions to write files to this directory. - Authorizations: The user executing this extraction requires authorizations for transaction
SE38(to create and run the program), display access to tablesMKPF,MSEG,MCH1,CDHDR,CDPOS,LTAK, andLTAP, and the ability to schedule background jobs (SM36/SM37).
a Sample Query abap
REPORT Z_PM_INVENTORY_EXTRACT.
" ====================================================================
" SELECTION SCREEN
" ====================================================================
SELECT-OPTIONS: s_budat FOR sy-datum OBLIGATORY.
SELECT-OPTIONS: s_werks FOR mseg-werks.
PARAMETERS: p_fpath TYPE string DEFAULT '/usr/sap/trans/tmp/inventory_log.csv' OBLIGATORY.
" ====================================================================
" DATA STRUCTURES
" ====================================================================
TYPES: BEGIN OF ty_event_log,
InventoryBatchLot TYPE charg,
ActivityName TYPE string,
EventTime TYPE string,
MaterialNumber TYPE matnr,
UserName TYPE xubname,
MovementType TYPE bwart,
Plant TYPE werks_d,
StorageLocation TYPE lgort_d,
Quantity TYPE menge_d,
MovementReasonCode TYPE grund,
END OF ty_event_log.
DATA: lt_event_log TYPE TABLE OF ty_event_log.
" ====================================================================
" DATA SELECTION
" ====================================================================
START-OF-SELECTION.
SELECT
mseg~charg AS InventoryBatchLot,
'Goods Receipt Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('101', '103', '105', '501', '521', '561')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
CASE mseg~shkzg
WHEN 'H' THEN 'Stock Posted to Quality Inspection'
WHEN 'S' THEN 'Quality Inspection Stock Released'
END AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '321' " For QI to Unrestricted
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Put-Away Transfer Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '311' AND mseg~shkzg = 'H' " Assume put-away is the credit side
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Internal Stock Transfer Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('301', '311', '313', '315')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
CASE mseg~bwart
WHEN '343' THEN 'Stock Status Changed to Blocked'
WHEN '344' THEN 'Stock Status Changed to Unrestricted'
END AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('343', '344')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Inventory Adjustment Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('701', '702', '711', '712')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Goods Issue for Delivery Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '601'
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Goods Issue for Production Posted' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '261'
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Sales Return Received' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart IN ('651', '653')
UNION ALL
SELECT
mseg~charg AS InventoryBatchLot,
'Stock Scrapped' AS ActivityName,
CONCAT( mkpf~cpudt, mkpf~cputm ) AS EventTime,
mseg~matnr AS MaterialNumber,
mkpf~usnam AS UserName,
mseg~bwart AS MovementType,
mseg~werks AS Plant,
mseg~lgort AS StorageLocation,
mseg~menge AS Quantity,
mseg~grund AS MovementReasonCode
FROM mseg
JOIN mkpf ON mkpf~mblnr = mseg~mblnr AND mkpf~mjahr = mseg~mjahr
WHERE mkpf~budat IN s_budat
AND mseg~werks IN s_werks
AND mseg~charg IS NOT NULL AND mseg~charg <> ''
AND mseg~bwart = '551'
UNION ALL
SELECT
ltap~charg AS InventoryBatchLot,
'Picking Initiated' AS ActivityName,
CONCAT( ltak~bdatu, ltak~bzeit ) AS EventTime,
ltap~matnr AS MaterialNumber,
ltak~bname AS UserName,
ltak~bwart AS MovementType,
ltap~werks AS Plant,
ltap~lgort AS StorageLocation,
ltap~nista AS Quantity,
'' AS MovementReasonCode
FROM ltap
JOIN ltak ON ltak~tanum = ltap~tanum
WHERE ltak~bdatu IN s_budat
AND ltap~werks IN s_werks
AND ltap~charg IS NOT NULL AND ltap~charg <> ''
UNION ALL
SELECT
SUBSTRING( cdhdr~objectid, 5, 18 ) AS InventoryBatchLot, " Object ID for BATCH is MATNR+WERKS+CHARG
'Batch Status Changed' AS ActivityName,
CONCAT( cdhdr~udate, cdhdr~utime ) AS EventTime,
SUBSTRING( cdhdr~objectid, 1, 4 ) AS MaterialNumber,
cdhdr~username AS UserName,
'' AS MovementType,
'' AS Plant,
'' AS StorageLocation,
0 AS Quantity,
'' AS MovementReasonCode
FROM cdhdr
JOIN cdpos ON cdpos~objectclas = cdhdr~objectclas
AND cdpos~objectid = cdhdr~objectid
AND cdpos~changenr = cdhdr~changenr
WHERE cdhdr~udate IN s_budat
AND cdhdr~objectclas = 'BATCH'
AND cdpos~tabname = 'MCH1'
AND cdpos~fname = 'ZUSTD'
INTO TABLE @lt_event_log.
" ====================================================================
" WRITE OUTPUT FILE
" ====================================================================
DATA: lv_string TYPE string.
DATA: lo_conv TYPE REF TO cl_abap_conv_out_ce.
lo_conv = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
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 = 'InventoryBatchLot,ActivityName,EventTime,MaterialNumber,UserName,MovementType,Plant,StorageLocation,Quantity,MovementReasonCode'.
TRANSFER lv_string TO p_fpath.
" Write Data
LOOP AT lt_event_log ASSIGNING FIELD-SYMBOL(<fs_log>).
CONCATENATE
<fs_log>-InventoryBatchLot
<fs_log>-ActivityName
<fs_log>-EventTime
<fs_log>-MaterialNumber
<fs_log>-UserName
<fs_log>-MovementType
<fs_log>-Plant
<fs_log>-StorageLocation
<fs_log>-Quantity
<fs_log>-MovementReasonCode
INTO lv_string
SEPARATED BY ','.
TRANSFER lv_string TO p_fpath.
ENDLOOP.
CLOSE DATASET p_fpath.
WRITE: 'Extraction complete. File written to:', p_fpath.