Mẫu dữ liệu đơn đặt hàng trong quy trình mua hàng đến thanh toán
Mẫu dữ liệu đơn đặt hàng trong quy trình mua hàng đến thanh toán
- Các thuộc tính nên thu thập
- Các hoạt động chính cần theo dõi
- Hướng dẫn trích xuất dữ liệu từ SAP ECC
Thuộc tính đơn đặt hàng trong quy trình mua hàng đến thanh toán
| Tên | Mô tả | ||
|---|---|---|---|
| Đơn đặt hàng PurchaseOrder | Mã định danh duy nhất của chứng từ đơn đặt hàng (PO), dùng làm trường hợp chính để theo dõi quy trình mua hàng. | ||
| Mô tả Số đơn đặt hàng là mã định danh trung tâm, liên kết mọi hoạt động từ lúc tạo đến khi nhận hàng và hoàn tất. Mỗi số đơn đặt hàng riêng biệt tương ứng với một lần thực hiện quy trình mua hàng. Trong process mining, thuộc tính này rất cần thiết để dựng lại toàn bộ hành trình của từng đơn mua. Thuộc tính cho phép phân tích chi tiết thời gian chu kỳ, các biến thể quy trình và việc tuân thủ cho từng đơn hàng, đồng thời làm nền tảng cho toàn bộ mô hình quy trình. Vì sao điều này quan trọng Đây là mã định danh cốt lõi, liên kết mọi sự kiện liên quan để bạn có thể phân tích toàn bộ vòng đời của từng đơn đặt hàng. Lấy dữ liệu ở đâu Bảng: EKKO, Trường: EBELN Ví dụ 450001762345000176244500017625 | |||
| Hoạt động Activity | Tên của sự kiện hoặc bước nghiệp vụ cụ thể diễn ra trong vòng đời đơn đặt hàng. | ||
| Mô tả Thuộc tính này mô tả một bước trong quy trình, chẳng hạn “Tạo đơn đặt hàng”, “Phê duyệt đơn đặt hàng” hoặc “Ghi nhận nhận hàng”. Trình tự các hoạt động này tạo thành luồng quy trình cho từng đơn đặt hàng. Phân tích trình tự, tần suất và thời gian giữa các hoạt động là trọng tâm của process mining. Việc này giúp tìm điểm nghẽn, vòng lặp xử lý lại và sai lệch so với quy trình chuẩn, từ đó hỗ trợ cải tiến có mục tiêu và chuẩn hóa quy trình. Vì sao điều này quan trọng Các hoạt động xác định từng bước của quy trình. Phân tích trình tự và thời điểm diễn ra giúp bạn thấy luồng quy trình thực tế, điểm nghẽn và các sai lệch. Lấy dữ liệu ở đâu Được tổng hợp từ nhiều bảng SAP và nhật ký giao dịch, chẳng hạn CDHDR/CDPOS để theo dõi thay đổi, EKBE cho nhận hàng/hóa đơn và EBAN cho yêu cầu mua hàng. Thường cần logic tùy chỉnh hoặc chương trình trích xuất để tạo dữ liệu này. Ví dụ Tạo đơn đặt hàngPhê duyệt đơn đặt hàngGhi nhận nhận hàng | |||
| Thời điểm sự kiện EventTime | Ngày và giờ chính xác khi hoạt động diễn ra. | ||
| Mô tả Dấu thời gian ghi nhận chính xác lúc một sự kiện xảy ra, chẳng hạn lúc đơn đặt hàng được phê duyệt hoặc lúc nhận hàng được hạch toán. Dữ liệu này xác định thứ tự thời gian của mọi hoạt động trong một trường hợp. Dấu thời gian là nền tảng cho process mining vì cho phép thực hiện mọi phân tích theo thời gian. Bạn có thể tính thời gian chu kỳ giữa các hoạt động, tìm chậm trễ, phân tích thông lượng quy trình và đo hiệu suất so với thỏa thuận mức dịch vụ (SLA). Vì sao điều này quan trọng Dấu thời gian này rất quan trọng để tính các chỉ số dựa trên thời lượng, chẳng hạn thời gian chu kỳ và điểm nghẽn, cũng như sắp xếp sự kiện theo trình tự thời gian. Lấy dữ liệu ở đâu Được tổng hợp từ nhiều trường ngày và giờ trong bảng SAP, chẳng hạn EKKO-AEDAT (ngày thay đổi), CDHDR-UDATE/UTIME (dấu thời gian nhật ký thay đổi) hoặc EKBE-BUDAT (ngày hạch toán). Ví dụ 2023-04-15T10:05:31Z2023-04-16T14:22:00Z2023-05-01T09:00:15Z | |||
| Giá trị đơn hàng OrderAmount | Tổng giá trị tiền tệ của một dòng đơn đặt hàng. | ||
| Mô tả Thuộc tính này thể hiện tổng giá trị của một dòng đơn đặt hàng cụ thể, được tính bằng số lượng nhân với đơn giá thuần. Để tính tổng giá trị đơn đặt hàng, cần cộng giá trị các dòng. Phân tích quy trình theo giá trị đơn hàng rất quan trọng để tìm các giao dịch giá trị cao có thể cần kiểm soát chặt hơn hoặc áp dụng luồng phê duyệt khác. Thuộc tính này cung cấp dữ liệu cho dashboard “Phân tích giá trị đơn đặt hàng” và giúp ưu tiên cải tiến những đơn hàng có ảnh hưởng tài chính lớn nhất. Vì sao điều này quan trọng Định lượng ảnh hưởng tài chính của từng đơn mua, giúp ưu tiên phân tích đơn hàng giá trị cao hoặc tìm cơ hội tiết kiệm chi phí. Lấy dữ liệu ở đâu Bảng: EKPO, Trường: NETWR (Giá trị thuần của đơn hàng). Ví dụ 1500.00250.7512345.50 | |||
| Loại chứng từ DocumentType | Mã phân loại các loại đơn đặt hàng khác nhau. | ||
| Mô tả Loại chứng từ là cấu hình trong SAP, kiểm soát dải số, lựa chọn trường và luồng quy trình tổng thể của đơn đặt hàng. Ví dụ, có thể có các loại riêng cho đơn đặt hàng tiêu chuẩn, đơn đặt hàng dịch vụ hoặc đơn hàng vận chuyển hàng tồn kho. Thuộc tính này là một chiều phân tích hữu ích vì các loại chứng từ khác nhau thường đi theo quy trình khác nhau. Lọc theo loại chứng từ giúp so sánh thời gian chu kỳ và luồng quy trình giữa các đơn hàng cùng loại. Vì sao điều này quan trọng Phân biệt các loại quy trình mua hàng, chẳng hạn mua tiêu chuẩn, mua dịch vụ hoặc trả hàng. Mỗi loại thường có luồng xử lý và kỳ vọng hiệu suất riêng. Lấy dữ liệu ở đâu Bảng: EKKO, Trường: BSART Ví dụ Đơn đặt hàng tiêu chuẩnĐơn đặt hàng khungĐơn hàng vận chuyển giữa các kho | |||
| Mã công ty CompanyCode | Mã định danh pháp nhân hoặc công ty thực hiện giao dịch mua. | ||
| Mô tả Mã công ty đại diện cho một pháp nhân độc lập trong SAP. Mọi giao dịch đều được hạch toán ở cấp mã công ty, nên đây là đơn vị tổ chức cơ bản. Phân tích quy trình theo mã công ty giúp so sánh hiệu quả mua hàng và mức độ tuân thủ giữa các đơn vị kinh doanh hoặc quốc gia. Bạn có thể tìm cách làm hiệu quả ở một đơn vị để áp dụng nơi khác, hoặc xác định đơn vị đang gặp khó khăn. Vì sao điều này quan trọng Đại diện cho pháp nhân, cho phép so sánh hiệu suất quy trình và kiểm tra tuân thủ giữa các bộ phận trong tổ chức. Lấy dữ liệu ở đâu Bảng: EKKO, Trường: BUKRS Ví dụ 10002100US01 | |||
| Mã nhà cung cấp VendorNumber | Mã định danh duy nhất của nhà cung cấp. | ||
| Mô tả Đây là mã xác định duy nhất nhà cung cấp hàng hóa hoặc dịch vụ. Mã này là dữ liệu chủ quan trọng trong quy trình mua hàng. Thuộc tính này rất cần thiết để phân tích theo nhà cung cấp. Bạn có thể đánh giá hiệu suất giao hàng, so sánh thời gian giao hàng giữa các nhà cung cấp và phân tích xu hướng chi tiêu. Đây là chiều phân tích chính của dashboard “Hiệu suất giao hàng của nhà cung cấp”. Vì sao điều này quan trọng Cho phép phân tích hiệu suất nhà cung cấp, giúp tìm nhà cung cấp đáng tin cậy và những nhà cung cấp gây chậm trễ hoặc vấn đề chất lượng. Lấy dữ liệu ở đâu Bảng: EKKO, Trường: LIFNR Ví dụ 100345V-20598700112 | |||
| Nhóm vật tư MaterialGroup | Phân loại vật tư hoặc dịch vụ có đặc điểm tương tự vào cùng một nhóm. | ||
| Mô tả Nhóm vật tư, hay danh mục mua hàng, dùng để phân loại hàng hóa hoặc dịch vụ được mua. Ví dụ: “Phần cứng CNTT”, “Văn phòng phẩm” hoặc “Dịch vụ chuyên môn”. Thuộc tính này rất quan trọng để phân tích chi tiêu và hiểu xu hướng mua hàng. Bạn có thể lọc quy trình theo danh mục để xem cách xử lý, người phê duyệt và nhà cung cấp của từng nhóm. Đây là chiều phân tích chính trong dashboard “Phân tích giá trị đơn đặt hàng”. Vì sao điều này quan trọng Cho phép phân đoạn quy trình theo danh mục sản phẩm hoặc dịch vụ, qua đó cho thấy sự khác biệt về cách xử lý, thời gian chu kỳ hoặc nhà cung cấp giữa các nhóm chi tiêu. Lấy dữ liệu ở đâu Bảng: EKPO, Trường: MATKL Ví dụ 00101Phần cứng CNTTDịch vụ tư vấn | |||
| Tên người dùng UserName | Mã người dùng của người thực hiện hoạt động. | ||
| Mô tả Thuộc tính này ghi lại tên người dùng SAP của nhân viên đã tạo, thay đổi hoặc phê duyệt chứng từ. Với các bước tự động, thuộc tính có thể hiển thị mã người dùng hệ thống hoặc người dùng chạy theo lô. Phân tích theo người dùng giúp xác định nhu cầu đào tạo, người có hiệu suất cao hoặc vấn đề tiềm ẩn về tuân thủ. Đây là dữ liệu quan trọng để xây dựng dashboard về phân bổ khối lượng công việc, tuân thủ ma trận phê duyệt và hiệu suất của từng nhóm hoặc cá nhân. Vì sao điều này quan trọng Gắn thao tác với từng người cụ thể, giúp phân tích hiệu suất, khối lượng công việc và mức độ tuân thủ quy định. Lấy dữ liệu ở đâu Bảng: EKKO, Trường: ERNAM (Người tạo); Bảng: CDHDR, Trường: USERNAME (Người thay đổi). Ví dụ JSMITHMBROWNBATCH_USER | |||
| Có thay đổi sau phê duyệt IsPostApprovalChange | Cờ cho biết đơn đặt hàng (PO) có thay đổi sau lần phê duyệt đầu tiên hay không. | ||
| Mô tả Thuộc tính boolean này có giá trị true nếu phát hiện hoạt động 'Đơn đặt hàng đã thay đổi' sau hoạt động 'Đơn đặt hàng đã được phê duyệt' trên cùng một PO. Thuộc tính này giúp xác định những thay đổi gây vấn đề ở giai đoạn muộn của quy trình. Trường được tính toán này hỗ trợ trực tiếp KPI 'Tỷ lệ thay đổi PO sau phê duyệt' và dashboard 'Làm lại và thay đổi đơn đặt hàng'. Trường giúp định lượng và làm nổi bật những thay đổi gây gián đoạn, có thể làm chậm tiến độ và cần phê duyệt lại. Qua đó, bạn có thể nhận ra vấn đề trong khâu xác định yêu cầu hoặc phạm vi ban đầu. Vì sao điều này quan trọng Đo trực tiếp khối lượng công việc phải làm lại sau phê duyệt, một KPI quan trọng để đánh giá tính ổn định và hiệu quả của quy trình. Tỷ lệ cao cho thấy yêu cầu ở các bước trước chưa được xác định tốt. Lấy dữ liệu ở đâu Đây là thuộc tính được tính toán dựa trên thứ tự hoạt động trong nhật ký sự kiện. Ví dụ truefalse | |||
| Giao hàng đúng hạn IsOnTimeDelivery | Cờ cho biết hàng hóa được nhận vào hoặc trước ngày giao hàng yêu cầu. | ||
| Mô tả Thuộc tính boolean này có giá trị true nếu dấu thời gian của hoạt động 'Đã ghi nhận nhận hàng' nằm vào hoặc trước 'Ngày giao hàng yêu cầu'. Thuộc tính này cho biết rõ từng dòng hàng trên PO được giao đúng hạn hay trễ. Thuộc tính này là cơ sở cho KPI 'Tỷ lệ nhận hàng đúng hạn'. Nhờ dễ tổng hợp và lọc các trường hợp đúng hạn hoặc trễ, bạn có thể phân tích hiệu suất nhà cung cấp và hiệu quả nhận hàng nội bộ đơn giản hơn. Vì sao điều này quan trọng Cung cấp chỉ số rõ ràng về việc giao hàng đúng hạn hay trễ, hỗ trợ trực tiếp KPI và dashboard theo dõi hiệu suất nhà cung cấp. Lấy dữ liệu ở đâu Đây là thuộc tính được tính bằng cách so sánh ngày ghi nhận nhận hàng (EKBE-BUDAT) với ngày giao hàng yêu cầu (EKPO-EINDT). Ví dụ truefalse | |||
| Hệ thống nguồn SourceSystem | Hệ thống được trích xuất dữ liệu. | ||
| Mô tả Thuộc tính này xác định nguồn gốc dữ liệu, thường là mã định danh của một hệ thống SAP ECC, chẳng hạn 'ECC_PROD_100'. Trong môi trường có nhiều hệ thống, thuộc tính giúp phân biệt các nguồn dữ liệu. Để quản trị và truy xuất nguồn gốc dữ liệu, việc biết hệ thống nguồn rất quan trọng. Thông tin này giúp bảo đảm tính toàn vẹn của dữ liệu và xử lý sự cố khi trích xuất hoặc kiểm tra chất lượng, nhất là khi dữ liệu được gộp từ nhiều hệ thống hoặc phân hệ ERP. Vì sao điều này quan trọng Xác định nguồn gốc dữ liệu, rất cần thiết cho việc quản trị, xác thực dữ liệu và quản lý phân tích trên nhiều hệ thống. Lấy dữ liệu ở đâu Thông thường, đây là giá trị tĩnh được thêm trong quá trình trích xuất dữ liệu để ghi nhãn hệ thống nguồn của tập dữ liệu. Ví dụ SAP_ECC_PRODECC_EU_100S4H_FIN | |||
| Lần cập nhật dữ liệu gần nhất LastDataUpdate | Dấu thời gian cho biết lần gần nhất dữ liệu được làm mới từ hệ thống nguồn. | ||
| Mô tả Thuộc tính này ghi lại ngày và giờ của lần trích xuất hoặc cập nhật dữ liệu gần nhất. Nhờ đó, bạn biết dữ liệu đang phân tích mới đến mức nào. Hiển thị thông tin này trên dashboard giúp người dùng biết insight dựa trên dữ liệu gần thời gian thực hay ảnh chụp dữ liệu trong quá khứ. Điều này giúp người dùng hiểu rõ giới hạn của dữ liệu và đưa ra quyết định dựa trên dữ liệu có thời điểm cập nhật xác định. Vì sao điều này quan trọng Cho người dùng biết dữ liệu được cập nhật đến thời điểm nào, để họ hiểu phân tích có phản ánh tình hình vận hành mới nhất hay không. Lấy dữ liệu ở đâu Dấu thời gian này được tạo và thêm vào khi quy trình trích xuất dữ liệu hoặc ETL chạy. Ví dụ 2023-10-27T02:00:00Z2023-10-28T02:00:00Z | |||
| Lý do từ chối RejectionReason | Mã hoặc nội dung giải thích lý do yêu cầu mua hàng hoặc đơn đặt hàng bị từ chối. | ||
| Mô tả Thuộc tính này ghi lại lý do cụ thể khi đơn đặt hàng bị từ chối trong quy trình phê duyệt. Thông tin này rất quan trọng để hiểu nguyên nhân gốc rễ của việc làm lại và chậm trễ. Phân tích lý do từ chối giúp bạn nhận diện các vấn đề thường gặp như giá không chính xác, vượt ngân sách hoặc chọn nhà cung cấp không đáp ứng yêu cầu tuân thủ. Từ đó, doanh nghiệp có thể xử lý nguyên nhân gốc rễ, nâng cao chất lượng tạo PO ban đầu và rút gọn quy trình phê duyệt. Vì sao điều này quan trọng Cho biết trực tiếp lý do phê duyệt không thành công, giúp bạn cải tiến đúng trọng tâm để giảm việc làm lại và rút ngắn thời gian phê duyệt. Lấy dữ liệu ở đâu Thông tin này có thể khó tìm. Thông tin có thể nằm trong các trường văn bản dài hoặc phụ thuộc vào cấu hình workflow tùy chỉnh. Thường cần có kiến thức chuyên sâu về cách triển khai hệ thống. Ví dụ Giá không chính xácVượt ngân sáchYêu cầu trùng lặp | |||
| Ngày giao hàng yêu cầu RequestedDeliveryDate | Ngày doanh nghiệp yêu cầu nhà cung cấp giao hàng hóa hoặc dịch vụ. | ||
| Mô tả Đây là ngày giao hàng mục tiêu ghi trong đơn đặt hàng, dùng làm mốc để đánh giá hiệu suất giao hàng thực tế. Ngày này rất cần thiết để tính KPI “Tỷ lệ nhận hàng đúng hạn”. So sánh ngày nhận hàng thực tế với ngày yêu cầu giúp tổ chức đo lường độ tin cậy của nhà cung cấp và hiệu quả nhận hàng nội bộ, đồng thời hỗ trợ trực tiếp cho dashboard “Hiệu suất giao hàng của nhà cung cấp”. Vì sao điều này quan trọng Đây là ngày giao hàng mục tiêu, cần thiết để tính KPI giao hàng đúng hạn và đánh giá độ tin cậy của nhà cung cấp. Lấy dữ liệu ở đâu Bảng: EKPO, Trường: EINDT Ví dụ 2023-06-102023-07-222023-08-01 | |||
| Nhà máy Plant | Địa điểm thực tế hoặc nhà máy nơi hàng hóa sẽ được giao. | ||
| Mô tả Nhà máy là đơn vị tổ chức đại diện cho cơ sở sản xuất, kho hàng hoặc địa điểm khác tiếp nhận hàng hóa hay dịch vụ. Phân tích theo nhà máy giúp bạn hiểu sự khác biệt giữa các khu vực trong quy trình mua sắm. Qua đó, bạn có thể phát hiện thời gian giao hàng của nhà cung cấp khác nhau giữa các địa điểm hoặc xác định nhà máy có quy trình nhận hàng kém hiệu quả, từ đó đánh giá mức độ đúng hạn của việc nhận hàng. Vì sao điều này quan trọng Cho biết địa điểm giao hàng, hữu ích khi phân tích khác biệt giữa các khu vực và hiệu quả logistics. Lấy dữ liệu ở đâu Bảng: EKPO, trường: WERKS Ví dụ 100011002000 | |||
| Nhóm mua hàng PurchasingGroup | Người mua hoặc nhóm người mua cụ thể chịu trách nhiệm cho hoạt động mua hàng. | ||
| Mô tả Nhóm mua hàng là cá nhân hoặc đội ngũ người mua chịu trách nhiệm cho một hoạt động mua hàng cụ thể. Đây thường là đầu mối liên hệ chính với nhà cung cấp. Thuộc tính này cho phép phân tích chi tiết hơn so với tổ chức mua hàng. Bạn có thể xem khối lượng công việc được phân bổ giữa những người mua ra sao và tìm khác biệt về hiệu suất ở cấp cá nhân, từ đó đưa ra quyết định phân bổ tài nguyên và đào tạo. Vì sao điều này quan trọng Cho biết chi tiết ai phụ trách từng giao dịch mua hàng, giúp phân tích khối lượng công việc và hiệu suất ở cấp người mua hoặc nhóm. Lấy dữ liệu ở đâu Bảng: EKKO, trường: EKGRP Ví dụ 001002N01 | |||
| Tên nhà cung cấp VendorName | Tên pháp lý của nhà cung cấp. | ||
| Mô tả Tên mô tả của nhà cung cấp, dễ đọc hơn mã nhà cung cấp. Thông tin này thường lấy từ dữ liệu chủ nhà cung cấp. Mã nhà cung cấp dùng để liên kết và xác định duy nhất, còn tên nhà cung cấp giúp dashboard và báo cáo dễ hiểu hơn. Nhờ đó, người dùng nghiệp vụ không cần biết mã nhà cung cấp vẫn có thể đọc kết quả phân tích. Vì sao điều này quan trọng Hiển thị tên nhà cung cấp dễ đọc, giúp người dùng nghiệp vụ hiểu dashboard và báo cáo nhanh hơn. Lấy dữ liệu ở đâu Bảng: LFA1, Trường: NAME1. Cần liên kết EKKO-LIFNR với LFA1-LIFNR. Ví dụ Staples Inc.Global Tech SolutionsOffice Supply Co. | |||
| Tiền tệ Currency | Mã tiền tệ của giá trị đơn đặt hàng. | ||
| Mô tả Thuộc tính này cho biết đơn đặt hàng được tính bằng loại tiền tệ nào, chẳng hạn USD, EUR hoặc GBP. Đây là thông tin cần thiết để hiểu các giá trị tiền tệ. Với tổ chức hoạt động trên nhiều quốc gia, tiền tệ rất quan trọng để phân tích tài chính chính xác. Thuộc tính này cho phép cộng gộp và so sánh giá trị đơn hàng phù hợp. Khi diễn giải các KPI tiền tệ, bạn cần xét đến loại tiền tệ được sử dụng. Vì sao điều này quan trọng Cung cấp thông tin cần thiết về loại tiền tệ, giúp phân tích tài chính chính xác, nhất là với tổ chức hoạt động ở nhiều quốc gia. Lấy dữ liệu ở đâu Bảng: EKKO, Trường: WAERS Ví dụ USDEURJPY | |||
| Tổ chức mua hàng PurchasingOrganization | Đơn vị tổ chức chịu trách nhiệm đàm phán giá và mua vật tư hoặc dịch vụ. | ||
| Mô tả Tổ chức mua hàng là đơn vị tổ chức chủ chốt trong SAP, chịu trách nhiệm về hoạt động mua sắm. Đơn vị này có thể tập trung cho toàn công ty hoặc phân quyền theo nhà máy hay khu vực. Phân tích hiệu suất quy trình theo tổ chức mua hàng giúp xác định nhóm mua hàng nào hoạt động hiệu quả nhất. Bạn có thể so sánh các chỉ số như thời gian chu kỳ, tỷ lệ xử lý lại và chi phí giữa các đơn vị, từ đó tìm cách làm hiệu quả và những nơi cần hỗ trợ. Vì sao điều này quan trọng Xác định nhóm mua hàng chịu trách nhiệm, giúp so sánh và phân tích hiệu suất giữa các đơn vị tổ chức. Lấy dữ liệu ở đâu Bảng: EKKO, Trường: EKORG Ví dụ 1000US01DE01 | |||
| Yêu cầu mua hàng PurchaseRequisition | Mã định danh của yêu cầu mua hàng có trước đơn đặt hàng. | ||
| Mô tả Thuộc tính này liên kết đơn đặt hàng với yêu cầu mua hàng ban đầu. Không phải đơn đặt hàng nào cũng có yêu cầu mua hàng trước đó. Liên kết này rất quan trọng để phân tích dashboard “Chuyển đổi từ yêu cầu mua hàng sang đơn hàng” và KPI “Tỷ lệ chuyển đổi từ yêu cầu mua hàng sang đơn đặt hàng”. Bạn có thể đo hiệu quả của quy trình đầu vào, từ yêu cầu ban đầu đến khi tạo đơn hàng chính thức, đồng thời tìm các đơn đặt hàng không tuân thủ được tạo mà không có yêu cầu mua hàng. Vì sao điều này quan trọng Liên kết đơn đặt hàng với yêu cầu ban đầu, giúp phân tích quy trình chuyển đổi từ yêu cầu mua hàng sang đơn đặt hàng và tìm các đơn hàng không có yêu cầu trước đó. Lấy dữ liệu ở đâu Bảng: EKPO, Trường: BANFN Ví dụ 1001589010015891 | |||
Hoạt động trong quy trình đơn đặt hàng mua hàng đến thanh toán
| Hoạt động | Mô tả | ||
|---|---|---|---|
| Ghi nhận nhận hàng | Hoạt động này ghi nhận hàng hóa thực tế được nhận từ nhà cung cấp theo một đơn đặt hàng cụ thể. Ghi nhận nhận hàng là thao tác rõ ràng, chẳng hạn qua giao dịch MIGO, tạo chứng từ vật tư và cập nhật tồn kho. | ||
| Vì sao điều này quan trọng Đây là mốc quan trọng để theo dõi hiệu suất giao hàng của nhà cung cấp và thời điểm bắt đầu quy trình kiểm tra hóa đơn. Mốc này được dùng để tính tỷ lệ giao hàng đúng hạn và thời gian nhận hàng. Lấy dữ liệu ở đâu Sự kiện được ghi nhận khi tạo chứng từ vật tư. Dấu thời gian là ngày hạch toán (MKPF-BUDAT) hoặc ngày tạo (MKPF-CPUDT) trong bảng tiêu đề chứng từ vật tư (MKPF), được liên kết với đơn đặt hàng qua bảng chi tiết (MSEG). Thu thập Dùng dấu thời gian hạch toán hoặc tạo trong bảng MKPF của chứng từ vật tư tham chiếu đến đơn đặt hàng. Loại sự kiện explicit | |||
| Gửi đơn đặt hàng cho nhà cung cấp | Hoạt động này ghi nhận thời điểm đơn đặt hàng đã phê duyệt được gửi chính thức cho nhà cung cấp, chẳng hạn qua EDI, email hoặc bản in. Sự kiện được ghi lại trong các bảng kiểm soát thông điệp khi thông điệp đầu ra được xử lý thành công. | ||
| Vì sao điều này quan trọng Đây là mốc quan trọng, bắt đầu tính thời gian giao hàng của nhà cung cấp. Phân tích khoảng thời gian từ sự kiện này đến lúc nhận hàng giúp đánh giá hiệu suất và mức độ giao hàng đúng hạn của nhà cung cấp. Lấy dữ liệu ở đâu Sự kiện được ghi trong bảng trạng thái thông điệp (NAST). Có thể lấy dấu thời gian từ NAST-DATVR và NAST-UHRVR khi trạng thái xử lý (NAST-VSTAT) là '1' (đã xử lý thành công) cho loại thông điệp đầu ra tương ứng của đơn đặt hàng. Thu thập Dùng dấu thời gian xử lý trong bảng NAST của thông điệp đầu ra cho đơn đặt hàng. Loại sự kiện explicit | |||
| Hoàn tất đơn đặt hàng | Sự kiện này cho biết một dòng đơn đặt hàng được xem là đã giao đủ. Thông thường, sự kiện được suy ra khi chỉ báo “Đã giao đủ” trên dòng đơn đặt hàng được thiết lập tự động hoặc thủ công. | ||
| Vì sao điều này quan trọng Hoạt động này là điểm kết thúc hợp lý của phần hoàn tất đơn hàng trong quy trình. Đây là dữ liệu cần thiết để tính tổng thời gian xử lý đơn đặt hàng từ lúc tạo đến khi hoàn tất. Lấy dữ liệu ở đâu Sự kiện được suy ra từ chứng từ thay đổi (CDHDR/CDPOS), ghi nhận thời điểm chỉ báo “Đã giao đủ” (EKPO-ELIKZ) được đặt thành 'X' cho một dòng đơn đặt hàng. Khi dòng cuối cùng được đánh dấu hoàn tất, toàn bộ đơn đặt hàng có thể được xem là đã hoàn tất. Thu thập Tìm dấu thời gian trong chứng từ thay đổi khi cờ EKPO-ELIKZ được thiết lập. Loại sự kiện inferred | |||
| Phê duyệt đơn đặt hàng | Sự kiện này ghi nhận đơn đặt hàng được phê duyệt lần cuối và đủ điều kiện gửi cho nhà cung cấp. Mốc quan trọng này thường được suy ra khi trạng thái phê duyệt của đơn đặt hàng chuyển sang trạng thái “đã phê duyệt hoàn toàn” hoặc “đã phê duyệt”. | ||
| Vì sao điều này quan trọng Hoạt động này rất quan trọng để tính KPI thời gian phê duyệt đơn đặt hàng và tìm điểm nghẽn trong workflow phê duyệt. Đây cũng là điều kiện cần trước hầu hết các bước tiếp theo, chẳng hạn gửi đơn hàng cho nhà cung cấp. Lấy dữ liệu ở đâu Sự kiện được suy ra bằng cách theo dõi nhật ký thay đổi (CDHDR/CDPOS) của bảng tiêu đề đơn đặt hàng (EKKO), để xác định thời điểm áp dụng mã phê duyệt cuối cùng hoặc khi chỉ báo trạng thái phê duyệt tổng thể (EKKO-FRGKE) chuyển sang “đã phê duyệt”. Thu thập Xác định dấu thời gian khi trạng thái phê duyệt tổng thể của đơn đặt hàng (EKKO-FRGKE) chuyển sang trạng thái phê duyệt cuối cùng. Loại sự kiện inferred | |||
| Tạo đơn đặt hàng | Hoạt động này ghi nhận thời điểm tạo đơn đặt hàng chính thức, một hợp đồng có tính ràng buộc với nhà cung cấp. Sự kiện được ghi lại khi người dùng tạo và lưu đơn đặt hàng, chẳng hạn qua giao dịch ME21N, tạo các bản ghi trong bảng EKKO và EKPO. | ||
| Vì sao điều này quan trọng Đây là mốc bắt đầu chính thức của vòng đời đơn đặt hàng. Mốc này giúp đo thời gian chuyển từ yêu cầu mua hàng sang đơn đặt hàng, cũng như tổng thời gian hoàn tất đơn hàng từ đầu đến cuối. Lấy dữ liệu ở đâu Lấy ngày tạo (EKKO-AEDAT) trong bảng tiêu đề đơn đặt hàng (EKKO) theo số đơn đặt hàng tương ứng (EKKO-EBELN). Thu thập Dùng dấu thời gian tạo trong bảng EKKO cho mỗi đơn đặt hàng mới. Loại sự kiện explicit | |||
| Tạo yêu cầu mua hàng | Hoạt động này ghi nhận thời điểm tạo yêu cầu chính thức về hàng hóa hoặc dịch vụ. Sự kiện được ghi lại khi người dùng lưu yêu cầu mua hàng mới, chẳng hạn bằng giao dịch ME51N. Thao tác này tạo một bản ghi riêng trong bảng EBAN. | ||
| Vì sao điều này quan trọng Đây là điểm bắt đầu chính của quy trình mua hàng. Phân tích khoảng thời gian từ sự kiện này đến lúc tạo đơn đặt hàng giúp đo lường hiệu quả chuyển nhu cầu nội bộ thành đơn hàng có thể xử lý. Lấy dữ liệu ở đâu Sự kiện được ghi nhận khi tạo bản ghi trong bảng tiêu đề yêu cầu mua hàng (EBAN). Ngày tạo (EBAN-BADAT) và giờ tạo là dấu thời gian của sự kiện. Thu thập Tìm các bản ghi mới trong bảng EBAN dựa trên ngày tạo. Loại sự kiện explicit | |||
| Gửi yêu cầu phê duyệt đơn đặt hàng | Sự kiện này cho biết đơn đặt hàng mới tạo hoặc vừa thay đổi đã được gửi đi phê duyệt theo chiến lược phê duyệt đã cấu hình. Sự kiện được suy ra khi chiến lược phê duyệt được kích hoạt và đơn đặt hàng chuyển sang trạng thái chờ phê duyệt. | ||
| Vì sao điều này quan trọng Phân biệt thời điểm tạo đơn đặt hàng với lúc bắt đầu phê duyệt giúp đo chính xác KPI thời gian phê duyệt. Nhờ đó, bạn có thể thấy khoảng chậm trước khi workflow phê duyệt bắt đầu. Lấy dữ liệu ở đâu Sự kiện được suy ra từ chứng từ thay đổi (CDHDR/CDPOS) của đơn đặt hàng (đối tượng EINKBELEG), cho thấy trạng thái phê duyệt được thiết lập lần đầu, hoặc từ thời điểm trạng thái phê duyệt tổng thể (EKKO-FRGKE) lần đầu chuyển sang giá trị cho biết quy trình phê duyệt đang diễn ra. Thu thập Tìm bản ghi chứng từ thay đổi đầu tiên kích hoạt chiến lược phê duyệt cho đơn đặt hàng. Loại sự kiện inferred | |||
| Nhập xác nhận dịch vụ | Với đơn đặt hàng dịch vụ, hoạt động này ghi nhận dịch vụ đã được cung cấp. Sự kiện được ghi lại khi tạo Bảng xác nhận dịch vụ (Service Entry Sheet), chẳng hạn qua giao dịch ML81N. | ||
| Vì sao điều này quan trọng Đây là bước tương đương với nhận hàng đối với dịch vụ và rất cần thiết để theo dõi việc hoàn tất đơn hàng dịch vụ. Bước này khởi động quy trình thanh toán dịch vụ. Lấy dữ liệu ở đâu Lấy ngày tạo (ESSR-ERDAT) trong bảng tiêu đề Bảng xác nhận dịch vụ (ESSR). Bảng ESLL chứa liên kết đến đơn đặt hàng. Thu thập Dùng dấu thời gian tạo trong bảng ESSR của các Bảng xác nhận dịch vụ được liên kết với đơn đặt hàng. Loại sự kiện explicit | |||
| Phê duyệt yêu cầu mua hàng | Sự kiện này ghi nhận yêu cầu mua hàng đã được phê duyệt chính thức và có thể chuyển thành đơn đặt hàng. Sự kiện được suy ra từ thay đổi trong các trường trạng thái phê duyệt của dữ liệu yêu cầu mua hàng, theo dõi qua workflow chiến lược phê duyệt của SAP. | ||
| Vì sao điều này quan trọng Theo dõi phê duyệt giúp tìm điểm nghẽn trước khi đặt hàng và bảo đảm tuân thủ chính sách phê duyệt. Chậm trễ ở bước này ảnh hưởng trực tiếp đến tổng thời gian của chu kỳ mua hàng. Lấy dữ liệu ở đâu Sự kiện được suy ra từ nhật ký thay đổi của bảng yêu cầu mua hàng (EBAN), cụ thể là các thay đổi trong trường trạng thái phê duyệt (ví dụ: EBAN-FRGZU), hoặc từ việc phân tích chứng từ thay đổi trong CDHDR/CDPOS cho đối tượng EBAN. Thu thập Theo dõi chứng từ thay đổi của các trường trạng thái phê duyệt trong EBAN để xác định dấu thời gian phê duyệt cuối cùng. Loại sự kiện inferred | |||
| Thay đổi đơn đặt hàng | Sự kiện này ghi nhận mọi thay đổi đối với đơn đặt hàng sau khi tạo, chẳng hạn thay đổi số lượng, giá hoặc ngày giao hàng. SAP ghi lại rõ các thay đổi này trong hệ thống chứng từ thay đổi. | ||
| Vì sao điều này quan trọng Thay đổi thường xuyên, nhất là sau khi phê duyệt, có thể cho thấy quy trình kém hiệu quả, kế hoạch ban đầu chưa tốt hoặc phạm vi công việc liên tục mở rộng. Hoạt động này rất cần thiết cho dashboard về xử lý lại và thay đổi đơn đặt hàng, cùng các KPI liên quan. Lấy dữ liệu ở đâu Các thay đổi được ghi rõ trong bảng tiêu đề chứng từ thay đổi (CDHDR) và bảng chi tiết (CDPOS) cho đối tượng đơn đặt hàng (EINKBELEG). Mỗi thay đổi tạo một bản ghi mới kèm dấu thời gian. Thu thập Trích xuất sự kiện thay đổi và dấu thời gian từ bảng CDHDR và CDPOS được liên kết với số đơn đặt hàng. Loại sự kiện explicit | |||
| Thực hiện kiểm tra chất lượng | Sự kiện này cho biết hàng hóa đã nhận được kiểm tra chất lượng. Thông thường, sự kiện được suy ra khi lô kiểm tra được tạo lúc nhận hàng có quyết định sử dụng trong phân hệ Quản lý chất lượng. | ||
| Vì sao điều này quan trọng Trong các ngành coi trọng chất lượng, hoạt động này giúp phân tích thời gian và kết quả kiểm tra. Chậm trễ ở đây có thể tạo điểm nghẽn giữa lúc nhận hàng và lúc hàng sẵn sàng để sử dụng. Lấy dữ liệu ở đâu Sự kiện được suy ra từ phân hệ Quản lý chất lượng. Lô kiểm tra được tạo trong bảng QALS khi nhận hàng. Hoạt động được ghi nhận khi tạo quyết định sử dụng trong bảng QAVE, kèm dấu thời gian. Thu thập Tìm dấu thời gian của quyết định sử dụng trong bảng QAVE cho lô kiểm tra được liên kết với chứng từ vật tư. Loại sự kiện inferred | |||
| Trả hàng cho nhà cung cấp | Sự kiện này ghi nhận hàng đã nhận được trả lại nhà cung cấp, thường do vấn đề chất lượng hoặc giao sai hàng. Sự kiện được ghi lại khi hạch toán chứng từ vật tư với loại dịch chuyển dành riêng cho hàng trả lại. | ||
| Vì sao điều này quan trọng Hoạt động này cho thấy vấn đề về chất lượng nhà cung cấp hoặc độ chính xác của đơn hàng, đồng thời là chỉ báo quan trọng về việc phải xử lý lại. Đây là dữ liệu cần thiết để tính KPI tỷ lệ sai lệch khi nhận hàng. Lấy dữ liệu ở đâu Sự kiện được ghi trong các bảng chứng từ vật tư (MKPF/MSEG) khi dùng loại dịch chuyển trả hàng, chẳng hạn '122' cho trả hàng cho nhà cung cấp. Ngày hạch toán (MKPF-BUDAT) là dấu thời gian. Thu thập Tìm chứng từ vật tư có loại dịch chuyển trả hàng, chẳng hạn 122, và tham chiếu đến đơn đặt hàng ban đầu. Loại sự kiện explicit | |||
| Từ chối đơn đặt hàng | Hoạt động này xảy ra khi người phê duyệt từ chối đơn đặt hàng trong workflow phê duyệt. Đây là sự kiện được suy ra từ thay đổi trạng thái trong dữ liệu chiến lược phê duyệt của đơn đặt hàng, cho biết đơn hàng đã bị từ chối. | ||
| Vì sao điều này quan trọng Theo dõi các trường hợp từ chối giúp phát hiện vấn đề về chất lượng dữ liệu đơn đặt hàng, việc không tuân thủ chính sách hoặc bất cập trong ma trận phê duyệt. Đơn hàng thường phải xử lý lại, làm tăng tổng thời gian chu kỳ. Lấy dữ liệu ở đâu Sự kiện được suy ra từ chứng từ thay đổi (CDHDR/CDPOS) về trạng thái phê duyệt đơn đặt hàng. Thông thường, việc từ chối được ghi nhận khi mã phê duyệt bị hủy hoặc một trạng thái từ chối cụ thể được thiết lập. Thu thập Theo dõi nhật ký thay đổi để tìm trường hợp hủy mã phê duyệt hoặc thay đổi trạng thái cho biết đơn hàng bị từ chối. Loại sự kiện inferred | |||
| Xóa đơn đặt hàng | Sự kiện này ghi nhận việc hủy hoặc xóa logic một dòng đơn đặt hàng, khiến dòng đó không thể tiếp tục xử lý, chẳng hạn nhận hàng hoặc lập hóa đơn. Sự kiện được suy ra khi chỉ báo xóa được thiết lập trên dòng đơn đặt hàng. | ||
| Vì sao điều này quan trọng Đây là hoạt động kết thúc, cho biết đơn hàng đã bị hủy. Phân tích lý do và thời điểm xóa đơn hàng có thể giúp phát hiện vấn đề trong việc lập kế hoạch nhu cầu hoặc chọn nhà cung cấp. Lấy dữ liệu ở đâu Sự kiện được suy ra từ chứng từ thay đổi (CDHDR/CDPOS), cho thấy chỉ báo xóa (EKPO-LOEKZ) được đặt thành 'L' cho một dòng đơn đặt hàng. Thu thập Tìm dấu thời gian trong chứng từ thay đổi khi cờ EKPO-LOEKZ được thiết lập. Loại sự kiện inferred | |||
Hướng dẫn trích xuất dữ liệu
Các bước
- Tạo chương trình ABAP: Mở ABAP Editor bằng mã giao dịch SE38. Nhập tên cho chương trình mới, chẳng hạn Z_PM_PO_EXTRACT, rồi nhấp 'Create'. Đặt tiêu đề như 'Trích xuất dữ liệu đơn mua hàng bằng Process Mining' và chọn loại 'Executable Program'.
- Định nghĩa màn hình chọn: Trong chương trình, định nghĩa các tham số trên màn hình chọn để người dùng lọc dữ liệu cần trích xuất. Các tham số chính gồm phạm vi ngày tạo đơn mua hàng, Mã công ty (BUKRS) và Loại chứng từ mua hàng (BSART).
- Định nghĩa cấu trúc dữ liệu: Khai báo cấu trúc bảng nội bộ khớp với định dạng nhật ký sự kiện cuối cùng. Cấu trúc này cần có đủ các thuộc tính bắt buộc và được đề xuất: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode và DocumentType.
- Triển khai logic chọn dữ liệu: Viết logic ABAP chính để chọn dữ liệu cho từng hoạt động trong số 14 hoạt động bắt buộc. Việc này gồm truy vấn nhiều bảng SAP như EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS và NAST. Dùng một chương trình con riêng (PERFORM) cho mỗi hoạt động để mã dễ quản lý.
- Chọn dữ liệu yêu cầu mua hàng: Truy vấn bảng EBAN để tìm sự kiện 'Purchase Requisition Created', rồi liên kết với đơn mua hàng qua bảng EKPO. Dùng các bảng nhật ký thay đổi (CDHDR, CDPOS) để xác định sự kiện 'Purchase Requisition Approved' bằng cách theo dõi thay đổi ở các trường trạng thái phát hành.
- Chọn các sự kiện chính của đơn mua hàng: Truy vấn bảng EKKO và EKPO để tìm sự kiện 'Purchase Order Created'. Dùng các bảng nhật ký thay đổi (CDHDR, CDPOS) trên đối tượng EINKBELEG để trích xuất các sự kiện 'Purchase Order Changed', 'Purchase Order Approved', 'Purchase Order Rejected', 'Purchase Order Completed' và 'Purchase Order Deleted' dựa trên thay đổi ở các trường cụ thể như chỉ báo phát hành và cờ xóa.
- Chọn sự kiện gửi thông tin đơn mua hàng: Truy vấn bảng NAST để tìm các bản ghi cho biết đơn mua hàng đã được gửi thành công, qua đó ghi nhận hoạt động 'Purchase Order Sent to Vendor'.
- Chọn sự kiện hàng hóa và dịch vụ: Truy vấn bảng EKBE để tìm các lần hạch toán chứng từ vật tư, xác định hoạt động 'Goods Receipt Posted' và 'Goods Returned' dựa trên loại luân chuyển. Truy vấn ESSR và ESLL để tìm phiếu xác nhận dịch vụ, qua đó ghi nhận 'Services Confirmation Entered'.
- Chọn sự kiện quản lý chất lượng: Nếu đang dùng mô-đun Quality Management, hãy truy vấn bảng QALS và QAVE để xác định thời điểm đưa ra quyết định sử dụng cho lô kiểm tra liên kết với đơn mua hàng. Sự kiện này tương ứng với hoạt động 'Quality Inspection Performed'.
- Kết hợp và định dạng dữ liệu: Gộp dữ liệu từ tất cả các lượt chọn vào một bảng nội bộ cuối cùng. Đảm bảo trường EventTime dùng định dạng nhất quán (ví dụ: YYYY-MM-DDTHH:MI:SS).
- Tạo chức năng tải tệp xuống: Thêm chức năng tải bảng nội bộ cuối cùng thành tệp. Nên dùng định dạng phân tách bằng tab hoặc CSV, có thể thực hiện bằng mô-đun chức năng GUI_DOWNLOAD.
- Chạy và lưu kết quả: Chạy chương trình bằng giao dịch SE38 hoặc SA38. Điền tiêu chí chọn rồi chạy báo cáo. Khi được nhắc, lưu tệp đầu ra vào máy tính với phần mở rộng .csv để sẵn sàng tải lên.
Cấu hình
- Khoảng ngày: Cần xác định khoảng ngày cụ thể để trích xuất, thường dựa trên ngày tạo đơn đặt hàng (EKKO-AEDAT). Khoảng 3-6 tháng thường là điểm bắt đầu phù hợp để cân bằng dung lượng dữ liệu và thông tin phân tích.
- Mã công ty (BUKRS): Lọc theo một hoặc nhiều mã công ty để chỉ trích xuất dữ liệu của các pháp nhân liên quan. Đây là tham số quan trọng để đảm bảo hiệu suất và tính phù hợp.
- Loại chứng từ mua hàng (BSART): Lọc theo loại chứng từ cụ thể, chẳng hạn 'NB' cho PO tiêu chuẩn, để tập trung phân tích vào quy trình thông thường và loại trừ các loại mua sắm đặc biệt nếu cần.
- Mức độ chi tiết dữ liệu: Dữ liệu được trích xuất ở cấp dòng hàng của đơn đặt hàng. Case ID là số đơn đặt hàng (EBELN). Tất cả sự kiện, kể cả sự kiện ở cấp dòng hàng như nhận hàng, đều được liên kết với Case ID chính này.
- Lưu ý về hiệu suất: Với tập dữ liệu lớn, hãy lên lịch chạy chương trình dưới dạng tác vụ nền (SM36) để tránh lỗi hết thời gian chờ. Đảm bảo có chỉ mục cơ sở dữ liệu trên các trường chính dùng trong mệnh đề WHERE, đặc biệt ở các bảng như CDHDR và CDPOS.
- Điều kiện tiên quyết: Người chạy báo cáo cần được cấp quyền truy cập ABAP workbench (SE38) để phát triển và quyền chạy chương trình. Người dùng cũng cần quyền đọc tất cả bảng liên quan, gồm EKKO, EKPO, EKBE, CDHDR, CDPOS, EBAN, NAST, ESSR và các bảng QM.
Truy vấn mẫu abap
REPORT Z_PM_PO_EXTRACT.
TABLES: ekko, ekpo, eban.
*&---------------------------------------------------------------------*
*& Data Structures for Event Log
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
purchaseorder TYPE ebeln,
activity TYPE string,
eventtime TYPE timestamp,
username TYPE ernam,
vendornumber TYPE lifnr,
orderamount TYPE netwr_ak,
materialgroup TYPE matkl,
companycode TYPE bukrs,
documenttype TYPE bsart,
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_aedat FOR ekko-aedat OBLIGATORY, " PO Creation Date
s_bukrs FOR ekko-bukrs, " Company Code
s_bsart FOR ekko-bsart, " PO Document Type
s_ebeln FOR ekko-ebeln. " PO Number
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
PERFORM get_po_headers.
IF gt_event_log IS NOT INITIAL.
PERFORM get_pr_created.
PERFORM get_pr_approved.
PERFORM get_po_created.
PERFORM get_po_release_events. " Approved, Rejected, Approval Requested
PERFORM get_po_sent_to_vendor.
PERFORM get_po_changed.
PERFORM get_goods_receipt_posted.
PERFORM get_services_confirmed.
PERFORM get_quality_inspection.
PERFORM get_goods_returned.
PERFORM get_po_completed.
PERFORM get_po_deleted.
PERFORM download_to_csv.
ELSE.
MESSAGE 'No Purchase Orders found for the given criteria.' TYPE 'I'.
ENDIF.
*&---------------------------------------------------------------------*
*& Form GET_PO_HEADERS (Base data)
*&---------------------------------------------------------------------*
FORM get_po_headers.
SELECT h~ebeln, h~lifnr, h~bukrs, h~bsart, p~netwr, p~matkl
FROM ekko AS h
INNER JOIN ekpo AS p ON h~ebeln = p~ebeln
INTO TABLE @DATA(lt_po_base)
WHERE h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND h~bsart IN @s_bsart
AND h~ebeln IN @s_ebeln.
SORT lt_po_base BY ebeln.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PR_CREATED
*&---------------------------------------------------------------------*
FORM get_pr_created.
DATA: lt_pr_events TYPE TABLE OF ty_event_log.
SELECT p~ebeln AS purchaseorder,
'Purchase Requisition Created' AS activity,
b~erdat AS event_date,
'000000' AS event_time,
b~ernam AS username,
h~lifnr AS vendornumber,
p~netwr AS orderamount,
p~matkl AS materialgroup,
h~bukrs AS companycode,
h~bsart AS documenttype
FROM ekpo AS p
JOIN eban AS b ON p~banfn = b~banfn AND p~bnfpo = b~bnfpo
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE p~ebeln IN @s_ebeln
AND p~banfn IS NOT NULL AND p~banfn <> ''
AND h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND h~bsart IN @s_bsart
INTO TABLE @DATA(lt_pr_created).
LOOP AT lt_pr_created ASSIGNING FIELD-SYMBOL(<fs_pr>).
DATA(ls_event) = CORRESPONDING ty_event_log(<fs_pr>).
CONCATENATE <fs_pr>-event_date <fs_pr>-event_time INTO DATA(lv_ts).
CONVERT DATE <fs_pr>-event_date TIME '000000' INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PR_APPROVED
*&---------------------------------------------------------------------*
FORM get_pr_approved.
DATA: lt_pr_list TYPE TABLE OF eban-banfn.
SELECT DISTINCT p~banfn FROM ekpo AS p
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE h~aedat IN @s_aedat
AND h~bukrs IN @s_bukrs
AND p~banfn IS NOT NULL AND p~banfn <> ''
INTO TABLE @lt_pr_list.
IF lt_pr_list IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime, p~fname, p~value_new
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectid = p~objectid AND h~changenr = p~changenr
FOR ALL ENTRIES IN @lt_pr_list
WHERE h~objectclas = 'BANF'
AND h~objectid = @lt_pr_list-table_line
AND p~tabname = 'EBAN'
AND p~fname = 'FRGZU'
INTO TABLE @DATA(lt_cd_pr).
LOOP AT lt_cd_pr ASSIGNING FIELD-SYMBOL(<fs_cd>) WHERE <fs_cd>-value_new = 'X'.
SELECT SINGLE p~ebeln, p~netwr, p~matkl, h~lifnr, h~bukrs, h~bsart
FROM ekpo AS p
JOIN ekko AS h ON p~ebeln = h~ebeln
WHERE p~banfn = @<fs_cd>-objectid(10)
INTO @DATA(ls_po_info).
IF sy-subrc = 0.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = ls_po_info-ebeln
activity = 'Purchase Requisition Approved'
username = <fs_cd>-username
vendornumber = ls_po_info-lifnr
orderamount = ls_po_info-netwr
materialgroup = ls_po_info-matkl
companycode = ls_po_info-bukrs
documenttype = ls_po_info-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_CREATED
*&---------------------------------------------------------------------*
FORM get_po_created.
LOOP AT lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>).
SELECT SINGLE aedat, ernam FROM ekko INTO @DATA(ls_ekko)
WHERE ebeln = @<fs_po>-ebeln.
IF sy-subrc = 0.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Created'
username = ls_ekko-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE ls_ekko-aedat TIME '000000' INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_RELEASE_EVENTS
*&---------------------------------------------------------------------*
FORM get_po_release_events.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime, p~value_new
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectid = p~objectid AND h~changenr = p~changenr
WHERE h~objectclas = 'EINKBELEG'
AND h~objectid IN lt_ebeln
AND p~tabname = 'EKKO'
AND p~fname = 'FRGKE'
INTO TABLE @DATA(lt_cd_po).
LOOP AT lt_cd_po ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
CASE <fs_cd>-value_new.
WHEN '2' OR 'R'. " Final Release
ls_event-activity = 'Purchase Order Approved'.
WHEN '1'. " Blocked
ls_event-activity = 'Purchase Order Rejected'.
WHEN OTHERS. " Any other change implies a pending state
ls_event-activity = 'Purchase Order Approval Requested'.
ENDCASE.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_SENT_TO_VENDOR
*&---------------------------------------------------------------------*
FORM get_po_sent_to_vendor.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT objky, erdat, eruhr, ernam
FROM nast
WHERE kapol = 'EF' AND objky IN lt_ebeln AND vstat = '1'
INTO TABLE @DATA(lt_nast).
LOOP AT lt_nast ASSIGNING FIELD-SYMBOL(<fs_nast>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_nast>-objky.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Sent to Vendor'
username = <fs_nast>-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_nast>-erdat TIME <fs_nast>-eruhr INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_CHANGED
*&---------------------------------------------------------------------*
FORM get_po_changed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT DISTINCT objectid, username, udate, utime
FROM cdhdr
WHERE objectclas = 'EINKBELEG' AND objectid IN lt_ebeln AND tcode <> 'ME21N' AND tcode <> 'ME22'
INTO TABLE @DATA(lt_cdhdr_chg).
LOOP AT lt_cdhdr_chg ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Changed'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_GOODS_RECEIPT_POSTED
*&---------------------------------------------------------------------*
FORM get_goods_receipt_posted.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT k~ebeln, m~cpudt, m~cputm, m~usnam, k~bewtp
FROM ekbe AS k JOIN mkpf AS m ON k~belnr = m~mblnr AND k~gjahr = m~mjahr
WHERE k~ebeln IN lt_ebeln AND k~bewtp = 'E' AND k~shkzg = 'S'
INTO TABLE @DATA(lt_gr).
LOOP AT lt_gr ASSIGNING FIELD-SYMBOL(<fs_gr>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_gr>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Goods Receipt Posted'
username = <fs_gr>-usnam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_gr>-cpudt TIME <fs_gr>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_SERVICES_CONFIRMED
*&---------------------------------------------------------------------*
FORM get_services_confirmed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT l~ebeln, h~erdat, h~eruhr, h~ernam
FROM essr AS h JOIN esll AS l ON h~lblni = l~lblni
WHERE l~ebeln IN lt_ebeln
INTO TABLE @DATA(lt_ses).
LOOP AT lt_ses ASSIGNING FIELD-SYMBOL(<fs_ses>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_ses>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Services Confirmation Entered'
username = <fs_ses>-ernam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_ses>-erdat TIME <fs_ses>-eruhr INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_QUALITY_INSPECTION
*&---------------------------------------------------------------------*
FORM get_quality_inspection.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT q~ebeln, v~vdatum, v~vzeit, v~vname
FROM qals AS q JOIN qave AS v ON q~prueflos = v~prueflos
WHERE q~ebeln IN lt_ebeln
INTO TABLE @DATA(lt_qm).
LOOP AT lt_qm ASSIGNING FIELD-SYMBOL(<fs_qm>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_qm>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Quality Inspection Performed'
username = <fs_qm>-vname
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_qm>-vdatum TIME <fs_qm>-vzeit INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_GOODS_RETURNED
*&---------------------------------------------------------------------*
FORM get_goods_returned.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT k~ebeln, m~cpudt, m~cputm, m~usnam
FROM ekbe AS k JOIN mkpf AS m ON k~belnr = m~mblnr AND k~gjahr = m~mjahr
WHERE k~ebeln IN lt_ebeln AND k~bwart = '122'
INTO TABLE @DATA(lt_ret).
LOOP AT lt_ret ASSIGNING FIELD-SYMBOL(<fs_ret>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_ret>-ebeln.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Goods Returned'
username = <fs_ret>-usnam
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_ret>-cpudt TIME <fs_ret>-cputm INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_COMPLETED
*&---------------------------------------------------------------------*
FORM get_po_completed.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime
FROM cdhdr AS h JOIN cdpos AS p ON h~changenr = p~changenr AND h~objectid = p~objectid
WHERE h~objectclas = 'EINKBELEG' AND h~objectid IN lt_ebeln AND p~tabname = 'EKPO' AND p~fname = 'ELIKZ' AND p~value_new = 'X'
INTO TABLE @DATA(lt_cd_comp).
LOOP AT lt_cd_comp ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Completed'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_PO_DELETED
*&---------------------------------------------------------------------*
FORM get_po_deleted.
DATA: lt_ebeln TYPE RANGE OF ebeln, ls_ebeln LIKE LINE OF lt_ebeln.
LOOP AT lt_po_base INTO DATA(ls_po_base).
ls_ebeln-sign = 'I'. ls_ebeln-option = 'EQ'. ls_ebeln-low = ls_po_base-ebeln.
APPEND ls_ebeln TO lt_ebeln.
ENDLOOP.
IF lt_ebeln IS INITIAL. RETURN. ENDIF.
SELECT h~objectid, h~username, h~udate, h~utime
FROM cdhdr AS h JOIN cdpos AS p ON h~changenr = p~changenr AND h~objectid = p~objectid
WHERE h~objectclas = 'EINKBELEG' AND h~objectid IN lt_ebeln AND p~tabname = 'EKPO' AND p~fname = 'LOEKZ' AND p~value_new = 'L'
INTO TABLE @DATA(lt_cd_del).
LOOP AT lt_cd_del ASSIGNING FIELD-SYMBOL(<fs_cd>).
READ TABLE lt_po_base ASSIGNING FIELD-SYMBOL(<fs_po>) WITH KEY ebeln = <fs_cd>-objectid.
IF sy-subrc <> 0. CONTINUE. ENDIF.
DATA(ls_event) = VALUE ty_event_log(
purchaseorder = <fs_po>-ebeln
activity = 'Purchase Order Deleted'
username = <fs_cd>-username
vendornumber = <fs_po>-lifnr
orderamount = <fs_po>-netwr
materialgroup = <fs_po>-matkl
companycode = <fs_po>-bukrs
documenttype = <fs_po>-bsart
).
CONVERT DATE <fs_cd>-udate TIME <fs_cd>-utime INTO TIME STAMP ls_event-eventtime TIME ZONE sy-zonlo.
APPEND ls_event TO gt_event_log.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form DOWNLOAD_TO_CSV
*&---------------------------------------------------------------------*
FORM download_to_csv.
DATA: lv_filename TYPE string.
DATA: lt_fieldnames TYPE TABLE OF string.
APPEND 'PurchaseOrder' TO lt_fieldnames.
APPEND 'Activity' TO lt_fieldnames.
APPEND 'EventTime' TO lt_fieldnames.
APPEND 'UserName' TO lt_fieldnames.
APPEND 'VendorNumber' TO lt_fieldnames.
APPEND 'OrderAmount' TO lt_fieldnames.
APPEND 'MaterialGroup' TO lt_fieldnames.
APPEND 'CompanyCode' TO lt_fieldnames.
APPEND 'DocumentType' TO lt_fieldnames.
DATA(lv_header) = REDUCE string( INIT h = '' FOR f IN lt_fieldnames NEXT h = h && f && cl_abap_char_utilities=>horizontal_tab ).
REPLACE LAST OCCURRENCE OF cl_abap_char_utilities=>horizontal_tab IN lv_header WITH cl_abap_char_utilities=>cr_lf.
DATA(lv_file_content) = lv_header.
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_log>).
DATA lv_line TYPE string.
DATA lv_eventtime_str TYPE string.
lv_eventtime_str = |{ <fs_log>-eventtime TIMESTAMP = ISO }|.
lv_line = <fs_log>-purchaseorder && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-activity && cl_abap_char_utilities=>horizontal_tab &&
lv_eventtime_str && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-username && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-vendornumber && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-orderamount && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-materialgroup && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-companycode && cl_abap_char_utilities=>horizontal_tab &&
<fs_log>-documenttype && cl_abap_char_utilities=>cr_lf.
CONCATENATE lv_file_content lv_line INTO lv_file_content.
ENDLOOP.
CALL METHOD cl_gui_frontend_services=>gui_download
EXPORTING
filename = 'C:\temp\po_event_log.csv'
filetype = 'ASC'
CHANGING
data_tab = lv_file_content. Các bước
- Thiết lập kết nối cơ sở dữ liệu: Xin thông tin đăng nhập chỉ đọc và thông tin kết nối (tên máy chủ, cổng, tên cơ sở dữ liệu) của cơ sở dữ liệu SAP ECC. Đảm bảo đã cài các công cụ cần thiết như DBeaver, SQL Developer hoặc SSMS.
- Xác định lược đồ SAP: Kết nối với cơ sở dữ liệu và xác định lược đồ SAP chính chứa các bảng. Tên thường gặp là SAPSR3, SAPHANADB hoặc một tên riêng tương tự tùy hệ thống. Nếu đây không phải lược đồ mặc định của tài khoản, bạn cần thêm tên lược đồ trước tên từng bảng trong truy vấn.
- Xem lại truy vấn SQL: Mở tập lệnh SQL được cung cấp bằng công cụ của bạn. Truy vấn này kết hợp nhiều bảng SAP để trích xuất 14 hoạt động riêng biệt trong quy trình từ mua hàng đến thanh toán.
- Tùy chỉnh tham số truy vấn: Tìm biểu thức bảng chung (CTE) PO_BASE ở đầu tập lệnh. Thay các giá trị giữ chỗ để xác định phạm vi trích xuất:
- [START_DATE] và [END_DATE]: Đặt khoảng thời gian phân tích, ví dụ '20230101' và '20230630'. Nên lọc theo trường AEDAT (Changed On).
- [COMPANY_CODE_1], [COMPANY_CODE_2]: Chỉ định các mã công ty SAP cần đưa vào.
- [DOC_TYPE_1], [DOC_TYPE_2]: Chỉ định các loại chứng từ đơn đặt hàng cần đưa vào.
- [Your SAP Schema]: Thay giá trị giữ chỗ này bằng tên lược đồ SAP thực tế trong toàn bộ tập lệnh.
- Chạy truy vấn: Chạy tập lệnh SQL đã tùy chỉnh trên cơ sở dữ liệu SAP. Thời gian chạy tùy thuộc vào khoảng thời gian, khối lượng dữ liệu và hiệu suất cơ sở dữ liệu.
- Kiểm tra kết quả: Khi truy vấn chạy xong, kiểm tra nhanh dữ liệu đầu ra. Xem số dòng có hợp lý không và các cột chính như PurchaseOrder, Activity và EventTime có dữ liệu như mong đợi không.
- Xuất dữ liệu sang CSV: Xuất toàn bộ kết quả từ ứng dụng SQL sang tệp CSV. Dùng mã hóa UTF-8 để tránh lỗi ký tự.
- Chuẩn bị tải lên: Đảm bảo tiêu đề cột trong tệp CSV khớp chính xác với tên thuộc tính bắt buộc: PurchaseOrder, Activity, EventTime, UserName, VendorNumber, OrderAmount, MaterialGroup, CompanyCode, DocumentType.
- Tải lên công cụ process mining: Tải tệp CSV hoàn chỉnh lên ứng dụng process mining để phân tích và trực quan hóa.
Cấu hình
- Điều kiện tiên quyết: Cần có quyền truy cập trực tiếp, chỉ đọc vào cơ sở dữ liệu SAP ECC nền. Người dùng cần đủ quyền để truy vấn các bảng như EKKO, EKPO, EKBE, EBAN, CDHDR, CDPOS và NAST.
- Lọc theo khoảng ngày: Cần áp dụng bộ lọc khoảng ngày để giới hạn dung lượng dữ liệu. Lọc theo EKKO.AEDAT (Ngày thay đổi PO) trong khoảng 3-6 tháng là điểm bắt đầu thường dùng. Khoảng ngày dài có thể khiến truy vấn chạy rất lâu.
- Bộ lọc dữ liệu chính: Để phân tích đúng trọng tâm, luôn lọc theo EKKO.BUKRS (Mã công ty) và EKKO.BSART (Loại chứng từ). Việc này giới hạn phạm vi vào các pháp nhân và quy trình kinh doanh liên quan.
- Lưu ý về hiệu suất: Truy vấn kết hợp nhiều bảng lớn, trong đó có các bảng lịch sử thay đổi (CDHDR, CDPOS), nên có thể tiêu tốn nhiều tài nguyên. Bạn nên chạy trích xuất ngoài giờ cao điểm hoặc trên cơ sở dữ liệu sao chép không dùng cho môi trường sản xuất để tránh ảnh hưởng đến hiệu suất hệ thống.
- Ghi nhật ký thay đổi chứng từ: Độ chính xác của các hoạt động như 'Đã phê duyệt', 'Bị từ chối', 'Đã hoàn tất' và 'Đã thay đổi' phụ thuộc vào việc bật ghi nhật ký thay đổi chứng từ cho các trường liên quan trong SAP. Hãy xác nhận với quản trị viên SAP rằng chức năng này đã được bật qua giao dịch SCDO.
Truy vấn mẫu sql
WITH PO_BASE AS (
SELECT
H.EBELN, -- Purchase Order Number
I.EBELP, -- Purchase Order Item
H.LIFNR, -- Vendor Number
H.BUKRS, -- Company Code
H.BSART, -- Document Type
I.NETWR, -- Order Amount (Item Level)
I.MATKL, -- Material Group
I.BANFN, -- Purchase Requisition Number
I.BNFPO -- Purchase Requisition Item
FROM [Your SAP Schema].EKKO AS H
JOIN [Your SAP Schema].EKPO AS I ON H.EBELN = I.EBELN
WHERE H.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' -- Filter on PO Change Date, e.g., '20230101' and '20231231'
AND H.BUKRS IN ('[COMPANY_CODE_1]', '[COMPANY_CODE_2]') -- Specify Company Codes
AND H.BSART IN ('[DOC_TYPE_1]', '[DOC_TYPE_2]') -- Specify PO Document Types
)
-- 1. Purchase Requisition Created
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Requisition Created' AS "Activity",
TO_TIMESTAMP(CONCAT(pr.ERDAT, '000000'), 'YYYYMMDDHH24MISS') AS "EventTime", -- Time is not available in EBAN
pr.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EBAN pr ON po.BANFN = pr.BANFN AND po.BNFPO = pr.BNFPO
WHERE po.BANFN IS NOT NULL AND po.BANFN <> ''
UNION ALL
-- 2. Purchase Requisition Approved
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Requisition Approved' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'BANF' AND ch.OBJECTID = po.BANFN
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EBAN' AND cp.FNAME = 'FRGZU' AND cp.VALUE_NEW = 'X' -- Release indicator set to 'released'
UNION ALL
-- 3. Purchase Order Created
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Created' AS "Activity",
TO_TIMESTAMP(CONCAT(ekko.ERDAT, ' ', ekko.ERZET), 'YYYYMMDD HH24MISS') AS "EventTime",
ekko.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKKO ekko ON po.EBELN = ekko.EBELN
UNION ALL
-- 4. Purchase Order Approval Requested / 5. Approved / 6. Rejected (from Change Docs)
SELECT
po.EBELN AS "PurchaseOrder",
CASE
WHEN cp.VALUE_NEW > cp.VALUE_OLD THEN 'Purchase Order Approval Requested'
WHEN cp.VALUE_NEW = ekko.FRGKE AND ekko.FRGKE = 'R' THEN 'Purchase Order Approved'
ELSE 'Purchase Order Rejected' -- Simplified logic, may need adjustment
END AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKKO ekko ON po.EBELN = ekko.EBELN
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID = po.EBELN
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKKO' AND cp.FNAME = 'FRGZU' -- Release status
UNION ALL
-- 7. Purchase Order Sent to Vendor
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Sent to Vendor' AS "Activity",
TO_TIMESTAMP(CONCAT(na.ERDAT, ' ', na.ERUHR), 'YYYYMMDD HH24MISS') AS "EventTime",
na.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].NAST na ON na.OBJKY = po.EBELN AND na.KSCHL = '[Your PO Output Type]' -- e.g., 'NEU'
WHERE na.VSTAT = '1' -- Successfully processed
UNION ALL
-- 8. Purchase Order Changed
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Changed' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID = po.EBELN
WHERE ch.TCODE IN ('ME22', 'ME22N') -- Filter for change transactions
UNION ALL
-- 9. Goods Receipt Posted
SELECT
ekbe.EBELN AS "PurchaseOrder",
'Goods Receipt Posted' AS "Activity",
TO_TIMESTAMP(CONCAT(mkpf.CPUDT, ' ', mkpf.CPUTM), 'YYYYMMDD HH24MISS') AS "EventTime",
mkpf.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM [Your SAP Schema].EKBE AS ekbe
JOIN [Your SAP Schema].MKPF AS mkpf ON ekbe.BELNR = mkpf.MBLNR AND ekbe.GJAHR = mkpf.MJAHR
JOIN PO_BASE AS po ON ekbe.EBELN = po.EBELN AND ekbe.EBELP = po.EBELP
WHERE ekbe.BEWTP = 'E' -- Goods Receipt
AND ekbe.SHKZG = 'S' -- Debit/Credit Indicator: Goods Receipt
UNION ALL
-- 10. Services Confirmation Entered
SELECT
po.EBELN AS "PurchaseOrder",
'Services Confirmation Entered' AS "Activity",
TO_TIMESTAMP(CONCAT(essr.ERDAT, ' ', essr.ERZET), 'YYYYMMDD HH24MISS') AS "EventTime",
essr.ERNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKBE ekbe ON po.EBELN = ekbe.EBELN AND po.EBELP = ekbe.EBELP
JOIN [Your SAP Schema].ESSR essr ON ekbe.LBLNI = essr.LBLNI
WHERE ekbe.BEWTP = 'L' -- Service Entry Sheet
UNION ALL
-- 11. Quality Inspection Performed
SELECT
po.EBELN AS "PurchaseOrder",
'Quality Inspection Performed' AS "Activity",
TO_TIMESTAMP(CONCAT(qave.VDATUM, ' ', qave.VZEIT), 'YYYYMMDD HH24MISS') AS "EventTime",
qave.VNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].EKBE ekbe ON po.EBELN = ekbe.EBELN AND po.EBELP = ekbe.EBELP
JOIN [Your SAP Schema].QALS qals ON qals.MBLNR = ekbe.BELNR AND qals.MJAHR = ekbe.GJAHR
JOIN [Your SAP Schema].QAVE qave ON qals.PRUEFLOS = qave.PRUEFLOS
WHERE ekbe.BEWTP = 'E' -- Linked to a Goods Receipt
UNION ALL
-- 12. Goods Returned
SELECT
ekbe.EBELN AS "PurchaseOrder",
'Goods Returned' AS "Activity",
TO_TIMESTAMP(CONCAT(mkpf.CPUDT, ' ', mkpf.CPUTM), 'YYYYMMDD HH24MISS') AS "EventTime",
mkpf.USNAM AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM [Your SAP Schema].EKBE AS ekbe
JOIN [Your SAP Schema].MKPF AS mkpf ON ekbe.BELNR = mkpf.MBLNR AND ekbe.GJAHR = mkpf.MJAHR
JOIN PO_BASE AS po ON ekbe.EBELN = po.EBELN AND ekbe.EBELP = po.EBELP
WHERE ekbe.BEWTP = 'E' -- Goods Movement
AND ekbe.SHKZG = 'H' -- Debit/Credit Indicator: Return
AND ekbe.BWART = '122' -- Movement type for return to vendor
UNION ALL
-- 13. Purchase Order Completed
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Completed' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID LIKE CONCAT(po.EBELN, po.EBELP, '%')
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKPO' AND cp.FNAME = 'ELIKZ' AND cp.VALUE_NEW = 'X' -- Delivery completed indicator
UNION ALL
-- 14. Purchase Order Deleted
SELECT
po.EBELN AS "PurchaseOrder",
'Purchase Order Deleted' AS "Activity",
TO_TIMESTAMP(CONCAT(ch.UDATE, ' ', ch.UTIME), 'YYYYMMDD HH24MISS') AS "EventTime",
ch.USERNAME AS "UserName",
po.LIFNR AS "VendorNumber",
po.NETWR AS "OrderAmount",
po.MATKL AS "MaterialGroup",
po.BUKRS AS "CompanyCode",
po.BSART AS "DocumentType"
FROM PO_BASE po
JOIN [Your SAP Schema].CDHDR ch ON ch.OBJECTCLASS = 'EINKBELEG' AND ch.OBJECTID LIKE CONCAT(po.EBELN, po.EBELP, '%')
JOIN [Your SAP Schema].CDPOS cp ON ch.OBJECTCLASS = cp.OBJECTCLASS AND ch.OBJECTID = cp.OBJECTID AND ch.CHANGENR = cp.CHANGENR
WHERE cp.TABNAME = 'EKPO' AND cp.FNAME = 'LOEKZ' AND cp.VALUE_NEW = 'L'; -- Deletion indicator Các bước
- Điều kiện cần và kết nối: Đảm bảo công cụ ETL của bên thứ ba đã cài đặt và được cấp phép sử dụng SAP Certified Connector. Trong bảng điều khiển quản trị của công cụ ETL, cấu hình kết nối mới đến hệ thống SAP ECC. Bạn cần tên máy chủ ứng dụng, số hệ thống, mã client và một tài khoản SAP riêng có quyền RFC phù hợp cùng quyền đọc bảng.
- Xác định bảng nguồn: Trong tác vụ ETL hoặc luồng dữ liệu, khai báo các bảng SAP cần dùng làm nguồn dữ liệu. Các bảng chính gồm EKKO (đầu đơn đặt hàng), EKPO (dòng đơn đặt hàng), EBAN (yêu cầu mua hàng), CDHDR (đầu chứng từ thay đổi), CDPOS (dòng chứng từ thay đổi), MSEG (phân đoạn chứng từ vật tư), MKPF (đầu chứng từ vật tư), NAST (trạng thái thông báo), ESSR (đầu phiếu ghi nhận dịch vụ) và QALS (lô kiểm tra).
- Trích xuất 'Purchase Order Created': Tạo luồng dữ liệu lấy nguồn từ bảng EKKO. Lọc bản ghi theo khoảng thời gian mong muốn, chẳng hạn dùng AEDAT, và phạm vi tổ chức, chẳng hạn BUKRS cho mã công ty, BSART cho loại chứng từ. Ánh xạ EKKO.EBELN thành PurchaseOrder, 'Purchase Order Created' thành Activity, rồi kết hợp AEDAT và ERZET để tạo EventTime. Ánh xạ các thuộc tính bắt buộc khác.
- Trích xuất 'Goods Receipt Posted': Tạo luồng dữ liệu riêng lấy nguồn từ MSEG và kết hợp với MKPF theo MBLNR và MJAHR. Lọc các loại di chuyển phù hợp, chẳng hạn '101'. Ánh xạ MSEG.EBELN thành PurchaseOrder, 'Goods Receipt Posted' thành Activity, rồi dùng MKPF.CPUDT và MKPF.CPUTM làm EventTime.
- Trích xuất sự kiện dựa trên thay đổi (phê duyệt, chỉnh sửa, xóa): Tạo luồng dữ liệu lấy nguồn từ CDHDR và CDPOS, kết hợp theo CHANGENR. Có thể dùng nguồn này để tạo nhiều hoạt động.
- Lọc OBJECTCLAS = 'EINKBELEG' và TABNAME = 'EKPO'.
- Với 'Purchase Order Approved', lọc các thay đổi ở trường trạng thái phê duyệt (chẳng hạn FNAME = 'FRGZU') khi giá trị mới (VALUE_NEW) thể hiện đã phê duyệt cuối cùng.
- Với 'Purchase Order Deleted', lọc các thay đổi ở chỉ báo xóa (FNAME = 'LOEKZ') khi giá trị mới là 'L'.
- Với 'Purchase Order Changed', lọc các thay đổi ở những trường liên quan khác, không bao gồm các trường trạng thái đã dùng cho hoạt động khác.
- Với tất cả sự kiện này, dùng CDHDR.UDATE và CDHDR.UTIME làm EventTime.
- Trích xuất sự kiện 'Purchase Requisition': Tạo luồng dữ liệu từ EBAN cho sự kiện 'Purchase Requisition Created'. Để liên kết sự kiện này với trường hợp PurchaseOrder, kết hợp EBAN với EKPO theo số yêu cầu (BANFN) và dòng hàng (BNFPO). Với 'Purchase Requisition Approved', dùng CDHDR/CDPOS cùng OBJECTCLAS = 'BANF'. Cần ánh xạ cẩn thận để liên kết sự kiện với đơn đặt hàng tương ứng.
- Trích xuất 'PO Sent to Vendor': Tạo luồng dữ liệu lấy nguồn từ bảng NAST. Lọc theo OBJECTKEY (chứa số đơn đặt hàng), loại đầu ra phù hợp (KSCHL) và trạng thái xử lý thành công (VSTAT = '1'). Dùng ERDAT và UHR làm EventTime.
- Kết hợp các luồng hoạt động: Dùng phép biến đổi 'Union' hoặc 'Merge' trong công cụ ETL để kết hợp đầu ra của tất cả luồng dữ liệu đã tạo ở các bước trước. Đảm bảo tên cột và kiểu dữ liệu nhất quán giữa các luồng (PurchaseOrder, Activity, EventTime, v.v.).
- Chuyển đổi kiểu và định dạng dữ liệu: Đảm bảo cột EventTime được chuyển sang định dạng dấu thời gian thống nhất, chẳng hạn YYYY-MM-DD HH:MM:SS. Chuyển OrderAmount sang định dạng số thập phân tiêu chuẩn.
- Xác định nơi lưu dữ liệu: Cấu hình đích hoặc 'sink' cho luồng dữ liệu đã kết hợp. Thường đây là tệp phẳng như CSV hoặc Parquet. Cấu hình dấu phân cách, ký tự bao quanh văn bản và tùy chọn tiêu đề.
- Chạy và kiểm tra: Chạy toàn bộ tác vụ ETL. Kiểm tra tệp đầu ra để đảm bảo có đủ 14 hoạt động, số dòng hợp lý và các thuộc tính chính có dữ liệu chính xác.
- Lên lịch và xuất dữ liệu: Sau khi kiểm tra, lên lịch chạy tác vụ ETL định kỳ, chẳng hạn mỗi đêm, để dữ liệu luôn được cập nhật. Tệp được tạo đã sẵn sàng để tải lên công cụ process mining.
Cấu hình
- Điều kiện tiên quyết: Cần có công cụ ETL thương mại (ví dụ: Informatica PowerCenter, Talend, SAP Data Services) cùng SAP Certified Connector tương ứng cho ECC. Cần có tài khoản người dùng SAP dạng dialog hoặc system, được cấp quyền S_RFC và S_TABU_DIS đối với các bảng cần thiết.
- Kết nối SAP: Cấu hình connector với máy chủ ứng dụng SAP, số hệ thống, client, tên người dùng và mật khẩu. Nên sử dụng Secure Network Communications (SNC).
- Lọc theo khoảng ngày: Bạn cần lọc theo khoảng ngày để giới hạn khối lượng dữ liệu. Thông thường, lọc EKKO.AEDAT (ngày tạo PO) trong 3 đến 12 tháng gần nhất. Hãy áp dụng bộ lọc ngay tại nguồn để tránh trích xuất quá nhiều dữ liệu từ SAP.
- Lọc phạm vi tổ chức: Luôn lọc theo EKKO.BUKRS (mã công ty). Bạn cũng nên cân nhắc lọc theo EKPO.WERKS (nhà máy) hoặc EKKO.EKORG (tổ chức mua hàng) để giới hạn phân tích vào một đơn vị kinh doanh cụ thể.
- Lọc loại chứng từ: Dùng EKKO.BSART để chỉ lấy các loại đơn đặt hàng cần phân tích, đồng thời loại trừ các giao dịch chuyển kho hoặc chứng từ nội bộ khác không thuộc quy trình P2P tiêu chuẩn.
- Tối ưu hiệu suất: Trích xuất dữ liệu từ các bảng chứng từ thay đổi (CDHDR, CDPOS) có thể mất nhiều thời gian. Hãy đảm bảo đã lọc theo OBJECTCLAS, OBJECTID và UDATE. Điều chỉnh mục 'Packet Size' trong SAP connector để tối ưu tốc độ truyền dữ liệu. Với hệ thống rất lớn, bạn có thể tải dữ liệu lịch sử ban đầu, sau đó lên lịch tải phần dữ liệu thay đổi.
Truy vấn mẫu sql
/*
This is a logical representation of the transformations performed within the ETL tool.
The tool's graphical interface will be used to configure these separate data flows, which are then combined with a UNION transformation.
Placeholders like [Your ETL Tool Functions] and [Filter Values] must be configured in the tool.
*/
-- 1. Purchase Requisition Created
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Created' AS Activity,
[Your ETL Tool Functions].DateTime(eban.ERDAT, eban.ERZET) AS EventTime,
eban.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM EBAN AS eban
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 2. Purchase Requisition Approved (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Requisition Approved' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EBAN AS eban ON cdhdr.OBJECTID = eban.BANFN
INNER JOIN EKPO AS ekpo ON eban.BANFN = ekpo.BANFN AND eban.BNFPO = ekpo.BNFPO
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'BANF' AND cdpos.TABNAME = 'EBAN' AND cdpos.FNAME = 'FRGZU' AND cdpos.VALUE_NEW = '[Final Release Indicator for PR]'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 3. Purchase Order Created
SELECT
EBELN AS PurchaseOrder,
'Purchase Order Created' AS Activity,
[Your ETL Tool Functions].DateTime(AEDAT, ERZET) AS EventTime,
ERNAM AS UserName,
LIFNR AS VendorNumber,
NULL AS OrderAmount, -- Amount is at item level
NULL AS MaterialGroup, -- Attribute is at item level
BUKRS AS CompanyCode,
BSART AS DocumentType
FROM EKKO
WHERE AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 4. Purchase Order Approval Requested / 5. Approved / 6. Rejected (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
CASE
WHEN cdpos.VALUE_NEW = '[Final Release Code]' THEN 'Purchase Order Approved'
WHEN cdpos.VALUE_NEW = '[Rejection Release Code]' THEN 'Purchase Order Rejected'
ELSE 'Purchase Order Approval Requested'
END AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKKO' AND cdpos.FNAME = 'FRGKE'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 7. Purchase Order Sent to Vendor
SELECT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Sent to Vendor' AS Activity,
[Your ETL Tool Functions].DateTime(nast.ERDAT, nast.UHR) AS EventTime,
nast.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM NAST AS nast
INNER JOIN EKKO AS ekko ON nast.OBJKY = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE nast.KAPPL = 'EF' AND nast.VSTAT = '1' AND nast.KSCHL IN ([Your PO Output Types])
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 8. Purchase Order Changed (inferred from change documents, simplified example)
SELECT DISTINCT
ekko.EBELN AS PurchaseOrder,
'Purchase Order Changed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKKO AS ekko ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekko.EBELN
INNER JOIN EKPO AS ekpo ON ekko.EBELN = ekpo.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.FNAME NOT IN ('FRGKE', 'FRGZU', 'LOEKZ', 'ELIKZ')
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 9. Goods Receipt Posted
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Receipt Posted' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '101' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 10. Services Confirmation Entered
SELECT
essr.EBELN AS PurchaseOrder,
'Services Confirmation Entered' AS Activity,
[Your ETL Tool Functions].DateTime(essr.ERDAT, essr.ERZET) AS EventTime,
essr.ERNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM ESSR AS essr
INNER JOIN EKKO AS ekko ON essr.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON essr.EBELN = ekpo.EBELN AND essr.EBELP = ekpo.EBELP
WHERE ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 11. Quality Inspection Performed
SELECT
qals.EBELN AS PurchaseOrder,
'Quality Inspection Performed' AS Activity,
[Your ETL Tool Functions].DateTime(qals.PASTRTERM, '000000') AS EventTime, -- Time is often not available
qals.PRUEFER AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM QALS AS qals
INNER JOIN EKKO AS ekko ON qals.EBELN = ekko.EBELN
INNER JOIN EKPO AS ekpo ON qals.EBELN = ekpo.EBELN AND qals.EBELP = ekpo.EBELP
WHERE qals.VCODE <> '' -- A usage decision code exists
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 12. Goods Returned
SELECT
mseg.EBELN AS PurchaseOrder,
'Goods Returned' AS Activity,
[Your ETL Tool Functions].DateTime(mkpf.CPUDT, mkpf.CPUTM) AS EventTime,
mkpf.USNAM AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM MSEG AS mseg
INNER JOIN MKPF AS mkpf ON mseg.MBLNR = mkpf.MBLNR AND mseg.MJAHR = mkpf.MJAHR
INNER JOIN EKPO AS ekpo ON mseg.EBELN = ekpo.EBELN AND mseg.EBELP = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE mseg.BWART = '122' AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 13. Purchase Order Completed (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Completed' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'ELIKZ' AND cdpos.VALUE_NEW = 'X'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]);
UNION ALL
-- 14. Purchase Order Deleted (inferred from change documents)
SELECT
ekpo.EBELN AS PurchaseOrder,
'Purchase Order Deleted' AS Activity,
[Your ETL Tool Functions].DateTime(cdhdr.UDATE, cdhdr.UTIME) AS EventTime,
cdhdr.USERNAME AS UserName,
ekko.LIFNR AS VendorNumber,
ekpo.NETWR AS OrderAmount,
ekpo.MATKL AS MaterialGroup,
ekko.BUKRS AS CompanyCode,
ekko.BSART AS DocumentType
FROM CDHDR AS cdhdr
INNER JOIN CDPOS AS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
INNER JOIN EKPO AS ekpo ON SUBSTRING(cdhdr.OBJECTID, 1, 10) = ekpo.EBELN AND SUBSTRING(cdhdr.OBJECTID, 11, 5) = ekpo.EBELP
INNER JOIN EKKO AS ekko ON ekpo.EBELN = ekko.EBELN
WHERE cdhdr.OBJECTCLAS = 'EINKBELEG' AND cdpos.TABNAME = 'EKPO' AND cdpos.FNAME = 'LOEKZ' AND cdpos.VALUE_NEW = 'L'
AND ekko.AEDAT BETWEEN '[START_DATE]' AND '[END_DATE]' AND ekko.BUKRS IN ([YOUR_COMPANY_CODES]); Sẵn sàng bắt đầu?
Mẫu này cung cấp cho bạn hướng dẫn cần thiết để tối ưu hóa quy trình đơn đặt hàng trong quy trình mua hàng đến thanh toán trên SAP ECC. Hãy bắt đầu khai thác dữ liệu để tìm ra thông tin hữu ích và nâng cao hiệu quả ngay hôm nay.
Tối ưu hóa đơn đặt hàng trong quy trình mua hàng đến thanh toán: Bắt đầu dùng thử miễn phí ngay hôm nay
Loại bỏ điểm nghẽn và giảm thời gian chu kỳ từ 30% trở lên.
Không cần thẻ tín dụng, bắt đầu chỉ trong vài phút