Mẫu dữ liệu cho quy trình xử lý hóa đơn mua hàng đến thanh toán
Mẫu dữ liệu cho quy trình xử lý hóa đơn 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 S/4HANA
Thuộc tính của quy trình xử lý hóa đơn mua hàng đến thanh toán
| Tên | Mô tả | ||
|---|---|---|---|
| Số hóa đơn InvoiceNumber | Mã định danh duy nhất của chứng từ hóa đơn nhà cung cấp, dùng làm mã hồ sơ chính của quy trình. | ||
| Mô tả Số hóa đơn là mã định danh duy nhất được gán cho mỗi hóa đơn nhà cung cấp trong SAP S/4HANA. Mã này liên kết mọi hoạt động liên quan, như tạo, lưu tạm, phê duyệt và thanh toán, thành một hồ sơ quy trình thống nhất. Trong process mining, thuộc tính này là nền tảng để theo dõi toàn bộ hành trình của từng hóa đơn. Nhờ đó, bạn có thể dựng lại quy trình từ lúc nhận đến khi thanh toán xong, rồi phân tích thời gian xử lý, điểm nghẽn và các biến thể ở cấp độ từng hóa đơn. Vì sao điều này quan trọng Đây là khóa thiết yếu để liên kết mọi sự kiện liên quan, giúp theo dõi đầy đủ vòng đời hóa đơn trong hệ thống. Lấy dữ liệu ở đâu Đây là Số chứng từ kế toán, nằm trong bảng BKPF, trường BELNR. Ví dụ 190000000119000000451900000132 | |||
| Tên hoạt động ActivityName | Tên hoạt động kinh doanh hoặc sự kiện xảy ra tại một thời điểm cụ thể đối với hóa đơn. | ||
| Mô tả Tên hoạt động mô tả một bước cụ thể hoặc một lần thay đổi trạng thái trong vòng đời xử lý hóa đơn. Ví dụ: 'Tạo chứng từ hóa đơn', 'Gửi hóa đơn để phê duyệt', 'Đặt chặn thanh toán' và 'Thực hiện thanh toán'. Thuộc tính này rất quan trọng để tạo sơ đồ quy trình, giúp thể hiện trực quan luồng hoạt động. Phân tích thứ tự, tần suất và thời gian giữa các hoạt động giúp xác định điểm nghẽn, các vòng lặp làm lại và những biến thể không tuân thủ. Đây là nền tảng của mọi phân tích process mining. Vì sao điều này quan trọng Thuộc tính này xác định các bước trong quy trình, giúp trực quan hóa sơ đồ quy trình và phân tích luồng cũng như các biến thể của quy trình. Lấy dữ liệu ở đâu Được xác định từ tổ hợp mã giao dịch SAP (SY-TCODE), trạng thái đối tượng chứng từ thay đổi (CDHDR/CDPOS) và các giá trị trường cụ thể cho biết trạng thái đã thay đổi. Ví dụ Tạm lưu hóa đơnPhê duyệt hóa đơnThực hiện thanh toán | |||
| Thời điểm sự kiện EventTime | Ngày và giờ chính xác khi hoạt động xảy ra. | ||
| Mô tả Thời điểm sự kiện là dấu thời gian ghi lại chính xác lúc một hoạt động xảy ra. Dữ liệu này cần thiết để tính thời lượng, thời gian xử lý và thời gian chờ giữa các bước trong quy trình. Trong phân tích process mining, dấu thời gian chính xác giúp đo lường các KPI hiệu suất như 'Thời gian xử lý hóa đơn trung bình' và 'Thời gian phê duyệt hóa đơn'. Phân tích khoảng thời gian giữa các hoạt động giúp doanh nghiệp xác định nơi hóa đơn bị chậm trễ và tìm cơ hội rút ngắn quy trình. Vì sao điều này quan trọng Dấu thời gian này là cơ sở cho mọi phân tích theo thời gian, bao gồm theo dõi hiệu suất, xác định điểm nghẽn và giám sát SLA. Lấy dữ liệu ở đâu Thường lấy từ các bảng chứng từ thay đổi CDHDR (phần đầu) và CDPOS (khoản mục), dùng các trường UDATE và UTIME. Với một số sự kiện, dữ liệu có thể lấy từ ngày tạo hoặc ngày nhập trong các bảng như BKPF (CPUDT, CPUTM). Ví dụ 2023-04-15T10:30:00Z2023-04-18T14:05:21Z2023-05-02T09:00:00Z | |||
| Đơn đặt hàng PurchasingDocument | Số đơn đặt hàng liên quan đến hóa đơn. | ||
| Mô tả Số chứng từ mua hàng liên kết hóa đơn nhà cung cấp với đơn đặt hàng (PO) ban đầu. Mối liên kết này là nền tảng cho quy trình đối chiếu ba bên, nhằm kiểm tra hóa đơn với đơn đặt hàng và phiếu nhận hàng. Phân tích theo thuộc tính này giúp tìm hiểu các vấn đề liên quan đến hóa đơn có PO và không có PO. Đây là dữ liệu quan trọng để điều tra sai lệch đối chiếu và đánh giá hiệu quả của khâu mua hàng trong quy trình. Vì sao điều này quan trọng Thuộc tính này liên kết hóa đơn với quy trình mua hàng, cần thiết để phân tích sai lệch đối chiếu và mức độ tuân thủ PO. Lấy dữ liệu ở đâu Thông tin này thường nằm trong bảng phân đoạn chứng từ BSEG, trường EBELN (Số chứng từ mua hàng). Ví dụ 450000123445000056784500009012 | |||
| Loại chứng từ DocumentType | Mã phân loại các loại chứng từ kế toán, chẳng hạn hóa đơn nhà cung cấp hoặc giấy báo có. | ||
| Mô tả Trong SAP, loại chứng từ giúp phân biệt các giao dịch kinh doanh. Ví dụ, 'KR' thường là hóa đơn nhà cung cấp tiêu chuẩn, còn 'KG' có thể là giấy báo có của nhà cung cấp. Phân tích theo loại chứng từ giúp chia quy trình thành các nhóm để hiểu cách xử lý từng loại giao dịch. Chẳng hạn, quy trình xử lý giấy báo có có thể khác đáng kể so với quy trình xử lý hóa đơn tiêu chuẩn. Cách phân nhóm này giúp thông tin chuyên sâu về quy trình chính xác và phù hợp hơn. Vì sao điều này quan trọng Thuộc tính này giúp phân biệt các loại giao dịch tài chính, chẳng hạn hóa đơn tiêu chuẩn và giấy báo có, vốn thường đi theo các luồng quy trình khác nhau. Lấy dữ liệu ở đâu Nằm trong bảng phần đầu chứng từ BKPF, trường BLART. Ví dụ KRREKG | |||
| Lý do chặn thanh toán PaymentBlockReason | Mã cho biết lý do hóa đơn bị chặn thanh toán. | ||
| Mô tả Khi hóa đơn bị chặn thanh toán, thuộc tính này cho biết lý do cụ thể, chẳng hạn 'Sai lệch số lượng' hoặc 'Không khớp giá'. Các lý do này được cấu hình trong SAP để chuẩn hóa cách xử lý ngoại lệ. Thuộc tính này rất quan trọng đối với dashboard 'Tần suất và thời gian chặn thanh toán'. Phân tích tần suất của từng lý do giúp xác định nguyên nhân gốc rễ gây chậm thanh toán, chẳng hạn vấn đề với một số nhà cung cấp, vật tư hoặc quy trình nội bộ, từ đó đưa ra biện pháp khắc phục phù hợp. Vì sao điều này quan trọng Thuộc tính này cho biết nguyên nhân cụ thể khiến khoản thanh toán bị chặn, giúp phân tích đúng trọng tâm để giảm chậm trễ và tăng tỷ lệ xử lý chính xác ngay từ đầu. Lấy dữ liệu ở đâu Nằm trong khoản mục nhà cung cấp của bảng BSEG, trường ZLSPR (Mã chặn thanh toán). Ví dụ RIA | |||
| Mã công ty CompanyCode | Đơn vị tổ chức đại diện cho một công ty độc lập về mặt pháp lý, nơi lập báo cáo tài chính. | ||
| Mô tả Mã công ty là đơn vị tổ chức cơ bản trong SAP Finance. Mỗi hóa đơn được gán cho một mã công ty cụ thể, xác định pháp nhân chịu trách nhiệm cho giao dịch. Trong process mining, lọc hoặc so sánh theo mã công ty là việc cần thiết để phân tích hiệu suất quy trình giữa các đơn vị kinh doanh, pháp nhân hoặc quốc gia. Cách này giúp xác định khác biệt giữa các khu vực về hiệu quả, tuân thủ và mức độ tự động hóa, từ đó hỗ trợ cải tiến đúng trọng tâm. Vì sao điều này quan trọng Thuộc tính này giúp phân nhóm và so sánh hiệu suất xử lý hóa đơn giữa các pháp nhân hoặc khu vực địa lý trong tổ chức. Lấy dữ liệu ở đâu Đây là trường tiêu chuẩn trong bảng phần đầu chứng từ BKPF, trường BUKRS. Ví dụ 1000US01DE01 | |||
| Mã nhà cung cấp VendorNumber | Mã định danh duy nhất của nhà cung cấp đã gửi hóa đơn. | ||
| Mô tả Mã nhà cung cấp xác định nhà cung cấp hoặc chủ nợ liên quan đến hóa đơn. Mã này liên kết giao dịch hóa đơn với dữ liệu chủ nhà cung cấp. Thuộc tính này rất quan trọng khi phân tích theo nhà cung cấp, chẳng hạn đánh giá 'Hiệu suất thanh toán cho nhà cung cấp' hoặc xác định nhà cung cấp thường gửi hóa đơn có vấn đề, dẫn đến ngoại lệ hoặc bị chặn thanh toán. Thuộc tính giúp quản lý quan hệ với nhà cung cấp và đánh giá độ tin cậy của họ. Vì sao điều này quan trọng Thuộc tính này cho phép phân tích hiệu suất quy trình theo nhà cung cấp, giúp nhận diện xu hướng, quản lý quan hệ và đánh giá các vấn đề liên quan đến nhà cung cấp. Lấy dữ liệu ở đâu Thường nằm trong bảng phân đoạn chứng từ kế toán BSEG, trường LIFNR. Ví dụ 100345700012V9832 | |||
| Ngày đến hạn thanh toán PaymentDueDate | Ngày cuối cùng phải thanh toán hóa đơn để tránh quá hạn. | ||
| Mô tả Ngày đến hạn thanh toán là ngày phải thanh toán cho nhà cung cấp, được tính dựa trên ngày hóa đơn và điều khoản thanh toán đã thỏa thuận. Đây là hạn chót quan trọng trong quy trình. Thuộc tính này cần thiết để tính KPI 'Tỷ lệ thanh toán đúng hạn' và xây dựng dashboard 'Hiệu suất thanh toán cho nhà cung cấp'. Bằng cách so sánh ngày thanh toán thực tế với ngày đến hạn, công ty có thể đo lường khả năng thực hiện nghĩa vụ thanh toán. Điều này ảnh hưởng đến quan hệ với nhà cung cấp và uy tín tài chính. Vì sao điều này quan trọng Đây là mốc chính để đo lường hiệu suất thanh toán đúng hạn, yếu tố quan trọng giúp duy trì quan hệ tốt với nhà cung cấp và tránh phí trả chậm. Lấy dữ liệu ở đâu Ngày này thường có sẵn trong khoản mục nhà cung cấp ở bảng BSEG, trường ZFBDT (Ngày cơ sở để tính ngày đến hạn). Ngày đến hạn ròng được tính từ ngày cơ sở này và điều khoản thanh toán. Ví dụ 2023-05-302023-06-152023-07-01 | |||
| Số tiền hóa đơn AmountInCompanyCodeCurrency | Tổng số tiền gộp của hóa đơn theo đồng tiền địa phương của mã công ty. | ||
| Mô tả Thuộc tính này thể hiện tổng giá trị hóa đơn. Đây là chỉ số quan trọng để hiểu tác động tài chính và quy mô hoạt động xử lý hóa đơn. Phân tích số tiền hóa đơn giúp ưu tiên xử lý nhanh các hóa đơn giá trị cao, xác định xu hướng chi tiêu và tìm mối liên hệ giữa vấn đề trong quy trình với giá trị tài chính. Ví dụ, bạn có thể kiểm tra xem hóa đơn giá trị cao có thường bị chặn hoặc mất nhiều thời gian phê duyệt hơn không. Vì sao điều này quan trọng Thuộc tính này cung cấp bối cảnh tài chính cho quy trình, cho phép phân tích theo giá trị tiền tệ, chẳng hạn xác định hóa đơn giá trị cao có được xử lý khác hay không. Lấy dữ liệu ở đâu Giá trị này thường được tính bằng tổng các khoản mục liên quan trong bảng BSEG, trường WRBTR (Số tiền theo đồng tiền địa phương). Ví dụ 1500.75125000.00850.20 | |||
| Tên người dùng UserName | Mã người dùng SAP của người hoặc hệ thống đã thực hiện hoạt động. | ||
| Mô tả Thuộc tính này xác định người dùng đã thực hiện một giao dịch cụ thể hoặc tạo chứng từ. Đó có thể là mã người dùng cá nhân hoặc mã hệ thống dùng cho các tác vụ chạy theo lô tự động. Phân tích theo người dùng giúp hiểu cách phân bổ khối lượng công việc, xác định nhu cầu đào tạo và phát hiện hành vi bất thường. Chẳng hạn, bạn có thể biết người dùng nào thường xử lý trường hợp ngoại lệ hoặc hóa đơn nào được xử lý tự động (ví dụ: người dùng 'BATCHUSER'), thông tin quan trọng để tính KPI 'Tỷ lệ tự động hóa hóa đơn'. Vì sao điều này quan trọng Thuộc tính này gắn các hoạt động trong quy trình với người dùng hoặc tài khoản hệ thống cụ thể, giúp phân tích khối lượng công việc, so sánh hiệu suất và phát hiện hoạt động tự động. Lấy dữ liệu ở đâu Lấy từ các trường như BKPF-USNAM (Người nhập) hoặc CDHDR-USERNAME (Người thay đổi). Ví dụ SMITHJMUELLERTWF-BATCH | |||
| Có làm lại IsRework | Cờ cho biết hóa đơn có trải qua các hoạt động làm lại hay không, chẳng hạn bị từ chối phê duyệt hoặc được gỡ chặn thanh toán. | ||
| Mô tả Thuộc tính này đánh dấu các hóa đơn đã trải qua một hoặc nhiều vòng làm lại. Có thể nhận diện việc làm lại qua một số chuỗi hoạt động cụ thể, chẳng hạn 'Hóa đơn được phê duyệt' sau 'Hóa đơn bị từ chối', hoặc 'Gỡ chặn thanh toán' sau 'Đặt chặn thanh toán'. Thuộc tính này giúp tính KPI 'Tỷ lệ hóa đơn phải làm lại'. Nhà phân tích có thể dễ dàng lọc và kiểm tra các trường hợp phải làm lại để hiểu nguyên nhân gốc rễ gây kém hiệu quả và lặp lại thao tác thủ công. Vì sao điều này quan trọng Thuộc tính này xác định các luồng quy trình kém hiệu quả, trong đó công việc phải làm lại, giúp định lượng phần việc lãng phí và tìm nguyên nhân gốc rễ của các ngoại lệ trong quy trình. Lấy dữ liệu ở đâu Được tính dựa trên thứ tự hoạt động trong nhật ký sự kiện. Ví dụ, nếu 'Hóa đơn bị từ chối' xuất hiện trong dấu vết của một hóa đơn, cờ này sẽ được đặt thành đúng. Ví dụ truefalse | |||
| Có tự động hóa IsAutomated | Cờ cho biết hoạt động có được thực hiện bởi người dùng hệ thống tự động hay không. | ||
| Mô tả Thuộc tính dạng đúng/sai này có giá trị đúng nếu người dùng gắn với hoạt động là tài khoản hệ thống hoặc tài khoản chạy theo lô đã biết, chẳng hạn 'WF-BATCH' hoặc 'SAP_SYSTEM'. Thuộc tính giúp phân biệt các bước xử lý thủ công và tự động. Thuộc tính này cần thiết để tính KPI 'Tỷ lệ tự động hóa hóa đơn'. Phân tích những phần nào trong quy trình được tự động hóa giúp doanh nghiệp đánh giá hiệu quả của các sáng kiến tự động hóa, đồng thời xác định cơ hội giảm thao tác thủ công và nâng cao hiệu quả. Vì sao điều này quan trọng Thuộc tính này phân biệt hoạt động thủ công với hoạt động do hệ thống thực hiện, là cơ sở để đo lường tỷ lệ tự động hóa và xác định cơ hội tự động hóa thêm. Lấy dữ liệu ở đâu Được xác định từ thuộc tính UserName. Tạo quy tắc hoặc bảng ánh xạ để phân loại các mã người dùng cụ thể là 'tự động hóa'. Ví dụ truefalse | |||
| Dấu thời gian trích xuất ExtractionTimestamp | Ngày và giờ dữ liệu được trích xuất từ hệ thống nguồn. | ||
| Mô tả Thuộc tính này ghi lại dấu thời gian của lần trích xuất dữ liệu. Qua đó, bạn biết dữ liệu đang phân tích trong công cụ process mining mới đến mức nào. Khi phân tích, thuộc tính này giúp xác định mức độ cập nhật của thông tin chuyên sâu. Đây là dữ liệu quan trọng đối với dashboard giám sát vận hành, giúp đảm bảo quyết định dựa trên thông tin mới nhất và quản lý hiệu quả chu kỳ làm mới dữ liệu. Vì sao điều này quan trọng Cho biết dữ liệu mới đến mức nào, giúp đảm bảo việc phân tích và báo cáo dựa trên thông tin hiện có mới nhất. Lấy dữ liệu ở đâu Đây không phải trường SAP. Công cụ trích xuất dữ liệu hoặc quy trình ETL tạo và thêm trường này khi lấy dữ liệu. Ví dụ 2023-10-27T02:00:00Z2023-10-28T02:00:00Z2023-10-29T02:00:00Z | |||
| Điều khoản thanh toán PaymentTerms | Mã quy định các điều kiện thanh toán đã thỏa thuận với nhà cung cấp, chẳng hạn ngày đến hạn và thời hạn được hưởng chiết khấu. | ||
| Mô tả Điều khoản thanh toán quy định cách thanh toán hóa đơn, bao gồm các khoản chiết khấu nếu thanh toán sớm. Ví dụ, 'Z030' có thể nghĩa là 'Thanh toán trong vòng 30 ngày, không tính chiết khấu'. Thuộc tính này cần thiết cho việc lập kế hoạch tài chính và tối ưu hóa vốn lưu động. Trong process mining, thuộc tính được dùng để tính 'Ngày đến hạn thanh toán' và xác định điều kiện hưởng chiết khấu thanh toán sớm, hỗ trợ trực tiếp KPI 'Tỷ lệ hưởng chiết khấu thanh toán sớm'. Vì sao điều này quan trọng Thuộc tính này quy định ngày đến hạn và mức chiết khấu, tác động trực tiếp đến KPI thanh toán đúng hạn và việc quản lý vốn lưu động. Lấy dữ liệu ở đâu Nằm trong khoản mục nhà cung cấp ở bảng BSEG, trường ZTERM (Mã điều khoản thanh toán). Ví dụ 0001Z030NT60 | |||
| Lý do đảo ngược ReversalReason | Mã cho biết lý do chứng từ hóa đơn bị đảo ngược. | ||
| Mô tả Nếu hóa đơn được ghi sổ sai, hóa đơn thường sẽ bị đảo ngược. Mã lý do đảo ngược giải thích vì sao thực hiện thao tác này, chẳng hạn 'Sai ngày ghi sổ' hoặc 'Lỗi nhập dữ liệu'. Phân tích lý do đảo ngược giúp xác định các lỗi thường gặp trong quy trình ghi sổ hóa đơn. Từ đó, doanh nghiệp có thể cải thiện đào tạo, tăng cường kiểm soát hệ thống hoặc xử lý các vấn đề lặp lại gây phát sinh công việc tài chính và hành chính. Vì sao điều này quan trọng Thuộc tính này giải thích lý do hủy hóa đơn, giúp xác định trực tiếp nguồn gây lỗi và công việc phải làm lại trong quy trình ghi sổ. Lấy dữ liệu ở đâu Nằm trong phần đầu của chứng từ gốc ở bảng BKPF, trường STGRD (Lý do đảo ngược). Ví dụ 010205 | |||
| Mã hệ thống nguồn SourceSystemId | Mã định danh của hệ thống SAP S/4HANA nguồn nơi dữ liệu được trích xuất. | ||
| Mô tả Thuộc tính này cho biết hệ thống gốc, chẳng hạn 'S4H_PROD' hoặc 'ERP_EU'. Thuộc tính đặc biệt quan trọng khi doanh nghiệp có nhiều hệ thống ERP hoặc kết hợp hệ thống cũ và hiện đại. Khi phân tích, thuộc tính này giúp so sánh hiệu suất quy trình giữa các hệ thống hoặc khu vực. Thuộc tính cũng xác định nguồn gốc dữ liệu, hỗ trợ quản trị dữ liệu và xử lý sự cố khi kết hợp dữ liệu từ nhiều nguồn trên một nền tảng process mining. Vì sao điều này quan trọng Thuộc tính này cho biết nguồn gốc dữ liệu, cần thiết cho việc quản trị dữ liệu và so sánh quy trình giữa các hệ thống hoặc địa điểm của công ty. Lấy dữ liệu ở đâu Giá trị này thường được lấy từ mã hệ thống SAP (sy-sysid) khi trích xuất dữ liệu hoặc được cấu hình thành giá trị tĩnh trong quy trình ETL. Ví dụ S4PS4H_PROD_100ECC_EU | |||
| Ngày hóa đơn InvoiceDate | Ngày nhà cung cấp phát hành chứng từ hóa đơn. | ||
| Mô tả Ngày hóa đơn, còn gọi là ngày chứng từ, là ngày nhà cung cấp ghi trên hóa đơn. Ngày này được dùng làm mốc bắt đầu để tính ngày đến hạn thanh toán theo điều khoản đã thỏa thuận. Trong phân tích, ngày này là dữ liệu cơ bản cho các phép tính tài chính, chẳng hạn xác định thời gian tồn đọng của hóa đơn và điều kiện hưởng chiết khấu thanh toán sớm. Đây là dữ liệu đầu vào quan trọng để tính KPI 'Tỷ lệ hưởng chiết khấu thanh toán sớm'. Vì sao điều này quan trọng Đây là mốc cơ sở để tính điều khoản thanh toán và ngày đến hạn, cần thiết cho việc quản lý vốn lưu động và tận dụng chiết khấu. Lấy dữ liệu ở đâu Nằm trong bảng phần đầu chứng từ BKPF, trường BLDAT (Ngày chứng từ). Ví dụ 2023-04-122023-05-152023-06-20 | |||
| Số chu kỳ phê duyệt ApprovalCycleCount | Số lần hóa đơn được gửi đi phê duyệt. | ||
| Mô tả Chỉ số này đếm số lần hoạt động 'Gửi hóa đơn để phê duyệt' xảy ra với một hóa đơn. Nếu số lần lớn hơn một, hóa đơn đã bị từ chối hoặc trả lại ít nhất một lần và cần bắt đầu chu kỳ phê duyệt mới. Thuộc tính này hỗ trợ trực tiếp KPI 'Tỷ lệ phê duyệt ngay lần đầu'. Phân tích các hóa đơn có nhiều chu kỳ phê duyệt giúp doanh nghiệp tìm ra lý do phê duyệt không thành công, chẳng hạn thiếu thông tin hoặc mã hóa sai, rồi cải thiện quy trình. Vì sao điều này quan trọng Thuộc tính này định lượng công việc phải làm lại trong quy trình con phê duyệt, giúp đo lường tỷ lệ xử lý chính xác ngay lần đầu và xác định lý do hóa đơn bị từ chối phê duyệt. Lấy dữ liệu ở đâu Được tính bằng cách đếm số lần hoạt động 'Gửi hóa đơn để phê duyệt' xảy ra với mỗi InvoiceNumber duy nhất. Ví dụ 123 | |||
| Số chứng từ tất toán. ClearingDocumentNumber | Số chứng từ tất toán hóa đơn, thường là chứng từ thanh toán. | ||
| Mô tả Số chứng từ tất toán liên kết một khoản mục hóa đơn chưa thanh toán với giao dịch tất toán khoản mục đó, gần như luôn là chứng từ thanh toán. Mối liên kết này xác nhận hóa đơn đã được thanh toán. Thuộc tính này là liên kết xác thực giữa hóa đơn và khoản thanh toán. Thuộc tính được dùng để xác định hoạt động 'Thực hiện thanh toán' và dấu thời gian tương ứng, cần thiết để tính thời gian xử lý từ đầu đến cuối và tỷ lệ thanh toán đúng hạn. Vì sao điều này quan trọng Thuộc tính này xác nhận hóa đơn đã được thanh toán và liên kết hóa đơn với giao dịch thanh toán cụ thể, rất quan trọng khi phân tích thời gian xử lý và hiệu suất thanh toán. Lấy dữ liệu ở đâu Nằm trong bảng phân đoạn chứng từ BSEG, trường AUGBL (Số chứng từ tất toán). Ví dụ 150000000115000000231500000088 | |||
| Thanh toán đúng hạn IsPaidOnTime | Cờ có giá trị đúng nếu hóa đơn được thanh toán vào hoặc trước ngày đến hạn. | ||
| Mô tả Thuộc tính dạng đúng/sai này được tính bằng cách so sánh ngày thanh toán thực tế (dấu thời gian của hoạt động 'Thực hiện thanh toán') với 'Ngày đến hạn thanh toán'. Thuộc tính cho biết rõ hóa đơn đã được thanh toán đúng hạn hay chưa. Đây là phép tính cốt lõi của KPI 'Tỷ lệ thanh toán đúng hạn'. Thuộc tính giúp lọc và phân tích dễ dàng các đặc điểm thường gặp ở khoản thanh toán trễ, chẳng hạn nhà cung cấp, mã công ty hoặc số tiền hóa đơn liên quan đến tình trạng chậm trễ. Vì sao điều này quan trọng Thuộc tính này đo lường trực tiếp mức độ tuân thủ điều khoản thanh toán, một KPI quan trọng trong quản lý quan hệ với nhà cung cấp và vận hành tài chính. Lấy dữ liệu ở đâu Được tính bằng cách so sánh EventTime của hoạt động 'Thực hiện thanh toán' với thuộc tính PaymentDueDate. (Payment Date <= PaymentDueDate). Ví dụ truefalse | |||
Hoạt động trong quy trình xử lý hóa đơn mua hàng đến thanh toán
| Hoạt động | Mô tả | ||
|---|---|---|---|
| Đảo ngược hóa đơn | Hoạt động này thể hiện việc đảo ngược một chứng từ hóa đơn đã ghi sổ trước đó. Đây là sự kiện kết thúc đối với hóa đơn sai, sau đó hóa đơn thường được nhập lại cho chính xác. | ||
| Vì sao điều này quan trọng Các lần đảo ngược cho thấy có lỗi nghiêm trọng chưa được phát hiện ở các bước trước. Theo dõi tần suất và nguyên nhân gốc rễ của những lỗi này là điều cần thiết để cải tiến quy trình và giảm sai lệch tài chính. Lấy dữ liệu ở đâu Lần đảo ngược được xác định khi tạo chứng từ đảo ngược. Phần đầu chứng từ gốc (BKPF) có số chứng từ đảo ngược (BKPF-STBLG) và ngược lại. Ngày ghi sổ của chứng từ đảo ngược là thời điểm xảy ra sự kiện. Thu thập Tìm các chứng từ có giá trị trong trường BKPF-STBLG và dùng ngày ghi sổ của chứng từ đảo ngược. Loại sự kiện explicit | |||
| Ghi sổ hóa đơn | Đây là sự kiện tài chính quan trọng, khi hóa đơn đã tạm lưu hoặc được phê duyệt chính thức được ghi sổ vào Sổ cái tổng hợp. Thao tác này ghi nhận khoản phải trả cho nhà cung cấp. | ||
| Vì sao điều này quan trọng Ghi sổ là cột mốc quan trọng, đánh dấu chuyển tiếp từ khâu nhập và phê duyệt dữ liệu sang giai đoạn thanh toán. Thời gian từ lúc tạo hóa đơn đến khi ghi sổ là thước đo quan trọng về hiệu quả xử lý nội bộ. Lấy dữ liệu ở đâu Sự kiện này được xác định bằng Ngày ghi sổ (BKPF-BUDAT) trên phần đầu chứng từ. Với chứng từ được lưu tạm trước, thời điểm chuyển sang trạng thái đã ghi sổ là dấu thời gian của sự kiện. Thu thập Dùng ngày ghi sổ (BKPF-BUDAT) làm dấu thời gian của sự kiện. Loại sự kiện explicit | |||
| Phê duyệt hóa đơn | Hoạt động này cho biết hóa đơn đã được người có thẩm quyền phê duyệt. Sự kiện được ghi nhận khi workflow phê duyệt kết thúc thành công hoặc khi chỉ báo giải phóng được thiết lập. | ||
| Vì sao điều này quan trọng Đây là một mốc quan trọng giúp hóa đơn đủ điều kiện thanh toán. Chậm phê duyệt là điểm nghẽn thường gặp. Theo dõi hoạt động này giúp xác định người phê duyệt hoặc bước xử lý chậm. Lấy dữ liệu ở đâu Có thể suy ra sự kiện này từ bước giải phóng cuối cùng trong workflow SAP hoặc bằng cách theo dõi thay đổi trường trạng thái giải phóng trong các bảng liên quan đến hóa đơn hoặc chứng từ mua hàng. Thu thập Suy ra từ sự kiện hoàn tất workflow hoặc thay đổi trong trường trạng thái giải phóng của chứng từ. Loại sự kiện inferred | |||
| Tạo chứng từ hóa đơn | Đây là sự kiện đầu tiên, đánh dấu thời điểm tạo chứng từ hóa đơn trong SAP. Sự kiện có thể được ghi nhận khi người dùng lưu chứng từ hóa đơn mới, ở trạng thái tạm lưu hoặc chưa ghi sổ. | ||
| Vì sao điều này quan trọng Hoạt động này đánh dấu thời điểm bắt đầu vòng đời xử lý hóa đơn. Phân tích thời gian từ sự kiện này đến các sự kiện khác rất quan trọng để đo tổng thời gian xử lý. Lấy dữ liệu ở đâu Sự kiện này được ghi nhận từ ngày và giờ tạo chứng từ (CPUDT, CPUTM) trong bảng tiêu đề chứng từ, thường là BKPF hoặc RBKP đối với hóa đơn logistics. Mã giao dịch (BKPF-TCODE), chẳng hạn FB60, MIRO hoặc MIR7, cho biết cách tạo chứng từ. Thu thập Dùng dấu thời gian tạo từ BKPF-CPUDT và BKPF-CPUTM của chứng từ hóa đơn. Loại sự kiện explicit | |||
| Thực hiện thanh toán | Đây là hoạt động cuối cùng trong quy trình tiêu chuẩn, khi khoản thanh toán được thực hiện và hóa đơn được tất toán. Điều này cho biết tiền đã được chuyển cho nhà cung cấp. | ||
| Vì sao điều này quan trọng Đây là điểm kết thúc vòng đời hóa đơn P2P. Sự kiện này rất cần thiết để tính tổng thời gian xử lý từ đầu đến cuối và đo lường tỷ lệ thanh toán đúng hạn so với ngày đến hạn. Lấy dữ liệu ở đâu Sự kiện này được ghi nhận từ thông tin tất toán trên khoản mục nhà cung cấp. Ngày tất toán (BSEG-AUGDT) và Chứng từ tất toán (BSEG-AUGBL) cho biết khoản thanh toán đã được thực hiện. Thu thập Dùng ngày tất toán (BSEG-AUGDT) trên khoản mục nhà cung cấp đã tất toán. Loại sự kiện explicit | |||
| Cập nhật dữ liệu hóa đơn | Hoạt động này ghi nhận thay đổi đối với chứng từ hóa đơn sau khi tạo. Việc này thường xảy ra trong các vòng lặp làm lại sau khi bị từ chối hoặc khi cần sửa lỗi. | ||
| Vì sao điều này quan trọng Cập nhật thường xuyên cho thấy có thể phải làm lại và dữ liệu đầu vào có vấn đề. Theo dõi các thay đổi này giúp đo lường công sức sửa lỗi và xác định những lỗi thường gặp. Lấy dữ liệu ở đâu Các thay đổi đối với trường quan trọng được ghi lại trong bảng nhật ký thay đổi của SAP: CDHDR (tiêu đề) và CDPOS (mục). Có thể tạo sự kiện bằng cách lọc các thay đổi liên quan đến đối tượng hóa đơn. Thu thập Trích xuất sự kiện thay đổi từ bảng CDHDR và CDPOS cho đối tượng hóa đơn. Loại sự kiện explicit | |||
| Đặt chặn thanh toán | Hoạt động này đặt chặn thanh toán cho hóa đơn để ngăn thanh toán. Nguyên nhân thường là sai lệch về giá hoặc số lượng, hoặc đang chờ ghi nhận giấy báo có. | ||
| Vì sao điều này quan trọng Chặn thanh toán là nguyên nhân chính gây thanh toán trễ và tranh chấp với nhà cung cấp. Phân tích tần suất, thời gian và lý do chặn rất quan trọng để cải thiện tỷ lệ thanh toán đúng hạn. Lấy dữ liệu ở đâu Sự kiện này được ghi nhận bằng cách theo dõi thay đổi trong trường Khóa chặn thanh toán (BSEG-ZLSPR) ở dòng hóa đơn. Nhật ký thay đổi trong CDHDR và CDPOS cung cấp dấu thời gian và người đặt chặn. Thu thập Xác định thời điểm trường BSEG-ZLSPR được điền thông qua chứng từ thay đổi (CDHDR/CDPOS). Loại sự kiện explicit | |||
| Gỡ chặn thanh toán | Sự kiện này thể hiện vấn đề đã được xử lý và chặn thanh toán trước đó được gỡ bỏ. Hóa đơn đủ điều kiện thanh toán trở lại. | ||
| Vì sao điều này quan trọng Khoảng thời gian từ lúc đặt chặn đến khi gỡ chặn là thời gian xử lý ngoại lệ trong quy trình. Rút ngắn khoảng thời gian này là yếu tố quan trọng để nâng cao hiệu quả và cải thiện quan hệ với nhà cung cấp. Lấy dữ liệu ở đâu Sự kiện này được ghi nhận khi trường Khóa chặn thanh toán (BSEG-ZLSPR) được xóa. Thay đổi được ghi lại trong bảng CDHDR và CDPOS, cung cấp dấu thời gian gỡ chặn. Thu thập Xác định thời điểm trường BSEG-ZLSPR được xóa thông qua chứng từ thay đổi (CDHDR/CDPOS). Loại sự kiện explicit | |||
| Gửi hóa đơn để phê duyệt | Hoạt động này đánh dấu thời điểm bắt đầu workflow phê duyệt chính thức cho hóa đơn. Thường có thể suy ra sự kiện này khi trạng thái hóa đơn chuyển thành 'chờ phê duyệt' hoặc khi một mục workflow được tạo. | ||
| Vì sao điều này quan trọng Đây là mốc bắt đầu đo thời gian phê duyệt. Biết thời điểm bắt đầu phê duyệt là điều cần thiết để xác định điểm nghẽn trong chính quy trình làm việc phê duyệt. Lấy dữ liệu ở đâu Thông thường có thể suy ra sự kiện này từ thời điểm bắt đầu SAP Business Workflow (bảng SWW_WI2OBJ) được liên kết với đối tượng hóa đơn, chẳng hạn BUS2081, hoặc từ thay đổi trong trường trạng thái tùy chỉnh ở tiêu đề chứng từ. Thu thập Suy ra từ thời điểm tạo mục workflow liên quan đến chứng từ hóa đơn. Loại sự kiện inferred | |||
| Tạm lưu hóa đơn | Hóa đơn đã được nhập vào hệ thống nhưng chưa được ghi sổ vào sổ cái tổng hợp. Tạm lưu giúp lưu hóa đơn chưa hoàn chỉnh hoặc để xem xét lại trước khi ghi sổ. | ||
| Vì sao điều này quan trọng Tạm lưu cho thấy quy trình đã chủ động tạm dừng. Theo dõi thời gian và tần suất hóa đơn được tạm lưu giúp xác định nguyên nhân chậm trễ trước khi bắt đầu chu kỳ ghi sổ và phê duyệt chính thức. Lấy dữ liệu ở đâu Có thể xác định sự kiện này qua chứng từ được tạo bằng giao dịch tạm lưu, chẳng hạn MIR7 hoặc FV60, hoặc bằng cách kiểm tra các trường trạng thái cụ thể trong bảng BKPF hay các bảng chứng từ tạm lưu chuyên dụng như VBKPF. Thu thập Xác định chứng từ được tạo bằng giao dịch tạm lưu hoặc kiểm tra trạng thái chứng từ tạm lưu. Loại sự kiện explicit | |||
| Tạo đề xuất thanh toán | Hóa đơn được chọn và đưa vào đề xuất thanh toán trong một đợt thanh toán. Đây là bước đầu tiên của quy trình thanh toán tự động. | ||
| Vì sao điều này quan trọng Hoạt động này cho biết doanh nghiệp dự định thanh toán. Khoảng trễ giữa bước này và lúc thực hiện thanh toán có thể cho thấy vấn đề trong quy trình chạy thanh toán, khâu phê duyệt hoặc liên lạc với ngân hàng. Lấy dữ liệu ở đâu Bạn có thể tìm thông tin này trong các bảng chạy thanh toán, cụ thể là REGUP, nơi lưu các khoản mục được đưa vào đề xuất thanh toán. Ngày chạy trong bảng REGUH tương ứng cung cấp dấu thời gian. Thu thập Xác định thời điểm hóa đơn xuất hiện trong bảng REGUP của một đợt chạy đề xuất thanh toán. Loại sự kiện explicit | |||
| Thực hiện thanh toán trễ hạn | Đây là sự kiện được tính toán, xảy ra khi hóa đơn được thanh toán sau ngày đến hạn đã tính. Sự kiện này được xác định bằng cách so sánh hai trường ngày. | ||
| Vì sao điều này quan trọng Hoạt động này hỗ trợ trực tiếp cho KPI thanh toán đúng hạn, đồng thời giúp xác định nhà cung cấp hoặc đơn vị kinh doanh thường xuyên thanh toán trễ. Tình trạng này có thể ảnh hưởng đến quan hệ với nhà cung cấp và dẫn đến các khoản phạt. Lấy dữ liệu ở đâu Sự kiện này được tính bằng cách so sánh Ngày tất toán (BSEG-AUGDT) với Ngày đến hạn ròng. Ngày đến hạn được tính từ Ngày cơ sở (BSEG-ZFBDT) và điều khoản thanh toán (BSEG-ZTERM). Thu thập Xác định bằng cách so sánh BSEG-AUGDT > (BSEG-ZFBDT + số ngày theo điều khoản thanh toán). Loại sự kiện calculated | |||
| Từ chối hóa đơn | Sự kiện này thể hiện hóa đơn bị từ chối trong quá trình phê duyệt. Việc này khiến quy trình phải làm lại, bao gồm sửa hóa đơn và gửi lại để phê duyệt. | ||
| Vì sao điều này quan trọng Hóa đơn bị từ chối là dấu hiệu quan trọng cho thấy quy trình kém hiệu quả hoặc dữ liệu có vấn đề. Phân tích tần suất và lý do từ chối giúp xác định cơ hội cải tiến và nhu cầu đào tạo. Lấy dữ liệu ở đâu Có thể suy ra sự kiện này từ các cập nhật trạng thái cụ thể trong workflow SAP, chẳng hạn trạng thái 'bị từ chối', hoặc từ sự kiện hủy workflow phê duyệt hiện tại và chuyển hóa đơn lại cho người xử lý. Thu thập Suy ra từ thay đổi trạng thái workflow cho biết hóa đơn bị từ chối. Loại sự kiện inferred | |||
Hướng dẫn trích xuất dữ liệu
Các bước
- Điều kiện tiên quyết và quyền truy cập: Đảm bảo người thực hiện trích xuất có đủ quyền trong SAP S/4HANA để truy cập các CDS View cần thiết. Các view chính gồm
I_InvoiceDocument,I_OperationalAcctgDocItem,I_ChangeDocument,I_ChangeDocumentItemvàI_PaymentProposalItem. Người dùng cũng cần quyền chạy truy vấn qua giao diện đã chọn, chẳng hạn dịch vụ OData hoặc kết nối SQL trực tiếp. - Chọn phương thức kết nối: Xác định cách kết nối với hệ thống SAP S/4HANA để chạy truy vấn SQL. Các phương thức thường dùng gồm SAP Data Services, SAP Data Intelligence, công cụ ETL của bên thứ ba có SAP connector hoặc kết nối SQL trực tiếp đến cơ sở dữ liệu SAP HANA nếu chính sách bảo mật của tổ chức cho phép.
- Xác định tham số trích xuất: Trước khi chạy truy vấn, hãy xác định các tham số chính. Chọn khoảng ngày trích xuất, chẳng hạn
CreationDatenằm trong khoảng từ'YYYY-MM-DD'đến'YYYY-MM-DD'. Đồng thời, xác định các giá trịCompanyCodecần đưa vào để giới hạn phạm vi dữ liệu. - Tùy chỉnh truy vấn SQL: Sao chép truy vấn SQL được cung cấp vào ứng dụng khách SQL hoặc công cụ trích xuất dữ liệu bạn chọn. Kiểm tra kỹ các placeholder như
'{StartDate}','{EndDate}'và('{CompanyCode1}', '{CompanyCode2}'). Thay chúng bằng các giá trị đã xác định ở bước trước. Bạn cũng có thể cần điều chỉnh tên trường trạng thái workflow theo cấu hình SAP cụ thể của mình. - Chạy truy vấn: Chạy toàn bộ truy vấn SQL trên cơ sở dữ liệu SAP S/4HANA hoặc qua lớp dịch vụ phù hợp. Truy vấn được thiết kế để lấy dữ liệu trên phạm vi rộng, nên thời gian chạy có thể khá lâu tùy theo lượng dữ liệu và khoảng ngày đã chọn. Theo dõi quá trình chạy để phát hiện lỗi hoặc hết thời gian chờ.
- Kiểm tra kết quả ban đầu: Khi truy vấn chạy xong, kiểm tra nhanh dữ liệu đầu ra. Đảm bảo các cột
InvoiceNumber,ActivityNamevàEventTimecó dữ liệu. Kiểm tra cộtActivityNamecó nhiều hoạt động khác nhau, không chỉ có 'Invoice Document Created'. - Xử lý chuyển đổi dữ liệu: Truy vấn được cấu trúc để tạo nhật ký sự kiện theo định dạng chuẩn. Tuy nhiên, hãy đảm bảo cột
EventTimedùng định dạng dấu thời gian nhất quán, chẳng hạnYYYY-MM-DDTHH:MM:SS. Khi cần, truy vấn sẽ kết hợp trường ngày và giờ thành một dấu thời gian duy nhất. - Xuất dữ liệu: Xuất tập kết quả cuối cùng từ công cụ của bạn thành tệp CSV (Comma-Separated Values). Định dạng này tương thích rộng rãi với các công cụ process mining, trong đó có ProcessMind.
- Chuẩn bị tải lên: Trước khi tải lên, xác nhận tệp CSV dùng mã hóa UTF-8 để tránh lỗi ký tự. Đảm bảo tiêu đề cột khớp chính xác với các thuộc tính bắt buộc:
InvoiceNumber,ActivityName,EventTime,UserName,CompanyCodevà các trường khác. - Tải lên ProcessMind: Tải tệp CSV đã chuẩn bị vào dự án process mining. Ánh xạ các cột trong tệp với trường mã hồ sơ, tên hoạt động và dấu thời gian tương ứng trong cấu hình mô hình dữ liệu của công cụ.
Cấu hình
- CDS View được sử dụng: Nguồn dữ liệu chính là các CDS View tiêu chuẩn của SAP. Các view quan trọng gồm
I_InvoiceDocumentcho dữ liệu tiêu đề,I_OperationalAcctgDocItemcho thông tin hạch toán tài chính và tất toán, cùngI_ChangeDocumentvàI_ChangeDocumentItemđể theo dõi thay đổi lịch sử của thuộc tính hóa đơn như chặn thanh toán và trạng thái workflow. - Lọc theo khoảng ngày: Cần lọc dữ liệu theo một khoảng ngày cụ thể để kiểm soát hiệu năng. Truy vấn được cung cấp dùng placeholder cho
CreationDatetrong viewI_InvoiceDocument. Nên bắt đầu với dữ liệu trong khoảng 3 đến 6 tháng. - Lọc theo mã công ty: Để dữ liệu trích xuất phù hợp và dễ quản lý, hãy luôn lọc theo một hoặc nhiều
CompanyCode. Truy vấn có placeholderWHERE inv.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}')cho mục đích này. - Lọc theo loại chứng từ: Bạn có thể thu hẹp phạm vi trích xuất bằng cách lọc theo
InvoiceDocumentType. Ví dụ, có thể lấy hóa đơn nhà cung cấp tiêu chuẩn (RE) nhưng loại trừ giấy báo có. Thêm điều kiện này vào mệnh đềWHEREcủa CTE đầu tiên. - Điều kiện tiên quyết: Người chạy truy vấn cần có quyền xem phù hợp đối với chứng từ tài chính và mua hàng trong các mã công ty đã chọn. Truy cập cơ sở dữ liệu HANA bên dưới bằng ứng dụng khách SQL không phải quyền mặc định và cần được cấp riêng.
- Lưu ý về hiệu năng: Trích xuất dữ liệu từ các bảng chứng từ thay đổi (
I_ChangeDocument,I_ChangeDocumentItem) có thể tốn nhiều tài nguyên. Cần lọc chặt theo ngày, mã công ty và lớp đối tượng (INCOMINGINVOICE) để tránh thời gian chạy kéo dài.
Truy vấn mẫu sql
WITH InvoiceBase AS (
SELECT
inv.InvoiceDocument,
inv.FiscalYear,
inv.CompanyCode,
inv.Supplier AS VendorNumber,
inv.DocumentType,
inv.GrossInvoiceAmountInCoCoCrcy AS AmountInCompanyCodeCurrency,
inv.NetDueDate AS PaymentDueDate,
inv.PurchasingDocument,
inv.CreationDateTime,
inv.CreatedByUser,
accdoc.AccountingDocument,
accdoc.ClearingDate,
accdoc.ClearingJournalEntry,
accdoc.PaymentBlockReason,
accdoc.IsReversed
FROM I_InvoiceDocument AS inv
LEFT JOIN I_OperationalAcctgDocItem AS accdoc
ON inv.AccountingDocument = accdoc.AccountingDocument
AND inv.FiscalYear = accdoc.FiscalYear
AND inv.CompanyCode = accdoc.CompanyCode
WHERE
inv.CreationDate BETWEEN '{StartDate}' AND '{EndDate}'
AND inv.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}')
)
-- 1. Invoice Document Created
SELECT
InvoiceDocument AS "InvoiceNumber",
'Invoice Document Created' AS "ActivityName",
CreationDateTime AS "EventTime",
CreatedByUser AS "UserName",
CompanyCode AS "CompanyCode",
VendorNumber AS "VendorNumber",
AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
PaymentDueDate AS "PaymentDueDate",
DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
PurchasingDocument AS "PurchasingDocument"
FROM InvoiceBase
UNION ALL
-- 2. Invoice Parked
SELECT
i.InvoiceDocument AS "InvoiceNumber",
'Invoice Parked' AS "ActivityName",
i.CreationDateTime AS "EventTime",
i.CreatedByUser AS "UserName",
i.CompanyCode AS "CompanyCode",
i.Supplier AS "VendorNumber",
i.GrossInvoiceAmountInCoCoCrcy AS "AmountInCompanyCodeCurrency",
i.NetDueDate AS "PaymentDueDate",
i.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
i.PurchasingDocument AS "PurchasingDocument"
FROM I_InvoiceDocument AS i
WHERE
i.InvoiceDocumentIsParked = 'X'
AND i.CreationDate BETWEEN '{StartDate}' AND '{EndDate}'
AND i.CompanyCode IN ('{CompanyCode1}', '{CompanyCode2}')
UNION ALL
-- 3, 4, 5. Workflow activities (Sent for Approval, Approved, Rejected) from Change Docs
SELECT
cdpos.ObjectValue AS "InvoiceNumber",
CASE
WHEN cdpos.ValueNew = '[StatusSentForApproval]' THEN 'Invoice Sent For Approval'
WHEN cdpos.ValueNew = '[StatusApproved]' THEN 'Invoice Approved'
WHEN cdpos.ValueNew = '[StatusRejected]' THEN 'Invoice Rejected'
END AS "ActivityName",
CAST(cdhdr.ChangeDate AS TIMESTAMP) + CAST(cdhdr.ChangeTime AS TIME) AS "EventTime",
cdhdr.UserName AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM I_ChangeDocument AS cdhdr
JOIN I_ChangeDocumentItem AS cdpos ON cdhdr.ChangeDocument = cdpos.ChangeDocument
JOIN InvoiceBase AS inv ON cdpos.ObjectValue = inv.InvoiceDocument
WHERE
cdhdr.ObjectClassName = 'INCOMINGINVOICE'
AND cdpos.FieldName = '[WorkflowStatusFieldName]'
AND cdpos.ValueNew IN ('[StatusSentForApproval]', '[StatusApproved]', '[StatusRejected]')
UNION ALL
-- 6. Invoice Data Updated
SELECT
cdpos.ObjectValue AS "InvoiceNumber",
'Invoice Data Updated' AS "ActivityName",
CAST(cdhdr.ChangeDate AS TIMESTAMP) + CAST(cdhdr.ChangeTime AS TIME) AS "EventTime",
cdhdr.UserName AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM I_ChangeDocument AS cdhdr
JOIN I_ChangeDocumentItem AS cdpos ON cdhdr.ChangeDocument = cdpos.ChangeDocument
JOIN InvoiceBase AS inv ON cdpos.ObjectValue = inv.InvoiceDocument
WHERE
cdhdr.ObjectClassName = 'INCOMINGINVOICE'
AND cdpos.FieldName IN ('GrossInvoiceAmount', 'DocumentDate', 'PaymentTerms')
AND cdhdr.ChangeDate BETWEEN '{StartDate}' AND '{EndDate}'
UNION ALL
-- 7 & 8. Payment Block Set/Removed
SELECT
inv.InvoiceDocument AS "InvoiceNumber",
CASE
WHEN cdpos.ValueNew <> '' AND cdpos.ValueOld = '' THEN 'Payment Block Set'
WHEN cdpos.ValueNew = '' AND cdpos.ValueOld <> '' THEN 'Payment Block Removed'
END AS "ActivityName",
CAST(cdhdr.ChangeDate AS TIMESTAMP) + CAST(cdhdr.ChangeTime AS TIME) AS "EventTime",
cdhdr.UserName AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
cdpos.ValueNew AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM I_ChangeDocument AS cdhdr
JOIN I_ChangeDocumentItem AS cdpos ON cdhdr.ChangeDocument = cdpos.ChangeDocument
JOIN InvoiceBase AS inv ON cdpos.ObjectValue = inv.AccountingDocument
WHERE
cdhdr.ObjectClassName = 'BELEG'
AND cdpos.TableName = 'BSEG'
AND cdpos.FieldName = 'ZLSPR'
AND ( (cdpos.ValueNew <> '' AND cdpos.ValueOld = '') OR (cdpos.ValueNew = '' AND cdpos.ValueOld <> '') )
UNION ALL
-- 9. Invoice Posted
SELECT
inv.InvoiceDocument AS "InvoiceNumber",
'Invoice Posted' AS "ActivityName",
CAST(accdoc.PostingDate AS TIMESTAMP) AS "EventTime",
accdoc.CreatedByUser AS "UserName",
inv.CompanyCode AS "CompanyCode",
inv.VendorNumber AS "VendorNumber",
inv.AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
inv.PaymentDueDate AS "PaymentDueDate",
inv.DocumentType AS "DocumentType",
accdoc.PaymentBlockReason AS "PaymentBlockReason",
inv.PurchasingDocument AS "PurchasingDocument"
FROM InvoiceBase AS inv
JOIN I_OperationalAcctgDocItem AS accdoc ON inv.AccountingDocument = accdoc.AccountingDocument
WHERE inv.AccountingDocument IS NOT NULL AND inv.IsReversed = FALSE
UNION ALL
-- 10. Payment Proposal Created
SELECT
item.InvoiceReference AS "InvoiceNumber",
'Payment Proposal Created' AS "ActivityName",
CAST(prun.PaymentRunDate AS TIMESTAMP) AS "EventTime",
prun.CreatedByUser AS "UserName",
item.CompanyCode AS "CompanyCode",
item.Supplier AS "VendorNumber",
item.AmountInTransactionCurrency AS "AmountInCompanyCodeCurrency",
item.NetDueDate AS "PaymentDueDate",
item.AccountingDocumentType AS "DocumentType",
item.PaymentBlockReason AS "PaymentBlockReason",
item.PurchasingDocument AS "PurchasingDocument"
FROM I_PaymentProposalItem as item
JOIN I_PaymentRun as prun ON item.PaymentRunName = prun.PaymentRunName
JOIN InvoiceBase AS inv ON item.InvoiceReference = inv.InvoiceDocument
UNION ALL
-- 11 & 12. Payment Executed / Late Payment Executed
SELECT
InvoiceDocument AS "InvoiceNumber",
CASE
WHEN ClearingDate > PaymentDueDate THEN 'Late Payment Executed'
ELSE 'Payment Executed'
END AS "ActivityName",
CAST(ClearingDate AS TIMESTAMP) AS "EventTime",
CAST(NULL AS VARCHAR(12)) AS "UserName", -- User for clearing is not always straightforward
CompanyCode AS "CompanyCode",
VendorNumber AS "VendorNumber",
AmountInCompanyCodeCurrency AS "AmountInCompanyCodeCurrency",
PaymentDueDate AS "PaymentDueDate",
DocumentType AS "DocumentType",
'' AS "PaymentBlockReason",
PurchasingDocument AS "PurchasingDocument"
FROM InvoiceBase
WHERE ClearingDate IS NOT NULL AND IsReversed = FALSE
UNION ALL
-- 13. Invoice Reversed
SELECT
rev.OriginalInvoiceDocument AS "InvoiceNumber",
'Invoice Reversed' AS "ActivityName",
rev.CreationDateTime AS "EventTime",
rev.CreatedByUser AS "UserName",
rev.CompanyCode AS "CompanyCode",
rev.Supplier AS "VendorNumber",
rev.GrossInvoiceAmountInCoCoCrcy AS "AmountInCompanyCodeCurrency",
CAST(NULL AS DATE) AS "PaymentDueDate",
rev.DocumentType AS "DocumentType",
CAST(NULL AS VARCHAR(1)) AS "PaymentBlockReason",
rev.PurchasingDocument AS "PurchasingDocument"
FROM I_InvoiceDocument AS rev
WHERE rev.OriginalInvoiceDocument IN (SELECT InvoiceDocument FROM InvoiceBase) AND rev.IsReversal = 'X' Các bước
- Xác nhận rằng bạn được phép truy cập chỉ đọc trực tiếp vào tenant SAP HANA hoặc lược đồ cơ sở dữ liệu. Tạo tài khoản cơ sở dữ liệu chỉ đọc có quyền với các bảng SAP cần thiết và mọi bảng lịch sử thay đổi hoặc workflow được phê duyệt. Dùng SAP HANA Database Explorer, SAP HANA Studio hoặc ứng dụng khách SQL đã được phê duyệt. Không dùng quyền ghi trên môi trường production.
- Xác nhận tên bảng và cột thực tế trong hệ thống S/4HANA đích. ACDOCA, BKPF và RBKP là các điểm bắt đầu tiêu chuẩn, nhưng dữ liệu workflow, chứng từ tạm lưu, đề xuất thanh toán, thực hiện thanh toán, lịch sử thay đổi và lịch sử chặn thanh toán có thể nằm trong các đối tượng riêng theo phiên bản hoặc khách hàng. Thay từng placeholder trong ngoặc vuông bằng đối tượng đã xác minh trong danh mục hệ thống và phù hợp với ý nghĩa nghiệp vụ.
- Xác định kỳ trích xuất bằng [Start timestamp] và [End timestamp]. Lấy dữ liệu chứng từ và sự kiện trong khoảng đủ rộng, thường là ba đến sáu tháng. Mở rộng khoảng này nếu ngày đến hạn hoặc sự kiện thanh toán trễ có thể nằm ngoài kỳ tạo hóa đơn.
- Xác định hồ sơ hóa đơn bằng khóa hóa đơn đã cấu hình. Truy vấn dùng InvoiceNumber làm mã hồ sơ và kết hợp nội bộ với mã công ty cùng năm tài chính khi cần để tránh trùng lặp. Xác nhận định nghĩa nghiệp vụ có yêu cầu thêm năm tài chính hoặc mã công ty vào mã hồ sơ ProcessMind hay không.
- Ánh xạ dữ liệu hóa đơn đã ghi sổ từ RBKP, BKPF và ACDOCA. Dùng RBKP cho thông tin tiêu đề hóa đơn, BKPF cho dấu thời gian và người dùng của chứng từ kế toán, ACDOCA cho nhà cung cấp, số tiền, chứng từ mua hàng, tất toán và thông tin kế toán liên quan đến thanh toán nếu có. Không mặc định rằng mọi trường đều có dữ liệu trong mọi tình huống ghi sổ.
- Ánh xạ các sự kiện lưu tạm, phê duyệt, từ chối, cập nhật, chặn thanh toán, đảo ngược, đề xuất và thực hiện thanh toán từ các nguồn đã xác minh theo hệ thống. Thay các view nguồn placeholder bằng view hoặc bảng được phê duyệt, có các trường dấu thời gian sự kiện, tham chiếu hóa đơn, người dùng, trạng thái và giá trị cũ, mới. Phải xuất từng hoạt động thành một dòng sự kiện riêng vì ProcessMind không tự suy ra sự kiện.
- Chạy toàn bộ truy vấn SQL trong phiên không phải production hoặc phiên chỉ đọc. Xem kế hoạch thực thi và giới hạn truy vấn theo mã công ty, loại chứng từ, năm tài chính và dấu thời gian sự kiện khi phù hợp. Tránh nối không giới hạn các bảng nhật ký lớn với bảng lịch sử.
- Kiểm tra kết quả theo các bước bên dưới. Xác nhận có đủ mọi cột bắt buộc,
EventTimecó dữ liệu cho mọi sự kiện,InvoiceNumbercó dữ liệu cho mọi hồ sơ và cả 13 tên hoạt động đều xuất hiện khi có dữ liệu nguồn tương ứng. - Xuất kết quả thành tệp phân tách được ProcessMind hỗ trợ, ưu tiên CSV mã hóa UTF-8, mỗi dòng là một sự kiện với các cột InvoiceNumber, ActivityName, EventTime, UserName, CompanyCode, VendorNumber, AmountInCompanyCodeCurrency, PaymentDueDate, DocumentType, PaymentBlockReason và PurchasingDocument. Giữ dấu thời gian theo một múi giờ nhất quán và bảo toàn số 0 ở đầu mã định danh.
- Tải nhật ký sự kiện lên ProcessMind và đặt InvoiceNumber làm mã hồ sơ, ActivityName làm cột hoạt động, EventTime làm cột dấu thời gian. Nếu cấu hình ProcessMind hỗ trợ thêm khóa hồ sơ, hãy dùng cùng chính sách khóa ghép đã áp dụng khi trích xuất.
Cấu hình
- Khoảng ngày: Với lần trích xuất đầu tiên, dùng khoảng thời gian cuốn chiếu từ ba đến sáu tháng. Lấy thêm dữ liệu lịch sử nếu sự kiện phê duyệt, thanh toán, tất toán, đảo ngược hoặc thanh toán trễ có thể xảy ra sau kỳ tạo hóa đơn.
- Phạm vi công ty: Lọc theo [Company code filter] và xác nhận các mã công ty được chọn có quyền truy cập để trích xuất.
- Phạm vi chứng từ: Lọc theo [Document type filter] và đưa vào các loại chứng từ đại diện cho hóa đơn nhà cung cấp, giấy báo có, hóa đơn lưu tạm và chứng từ đảo ngược trong quy trình đích.
- Mã hồ sơ: Dùng InvoiceNumber theo định nghĩa quy trình. Nếu số hóa đơn không duy nhất trên toàn hệ thống, hãy giữ mã công ty và năm tài chính trong kết quả nguồn hoặc cấu hình khóa hồ sơ ghép theo mô hình ProcessMind.
- Nguồn sự kiện: Xác minh nguồn dữ liệu thực tế cho thay đổi trạng thái workflow, quyết định phê duyệt, lưu tạm, lịch sử thay đổi, chặn thanh toán, đề xuất thanh toán và thực hiện thanh toán. Các nguồn này khác nhau tùy phiên bản S/4HANA, phạm vi đã kích hoạt, thiết kế workflow và phần mở rộng riêng của khách hàng.
- Quy tắc dấu thời gian: Chọn dấu thời gian của sự kiện nghiệp vụ, không dùng dấu thời gian trích xuất. Ghi lại múi giờ và chuyển đổi nhất quán mọi dấu thời gian sự kiện trước khi tải lên.
- Quy tắc số tiền: Dùng số tiền theo nội tệ của mã công ty và xác nhận nguồn dữ liệu lưu dấu nợ, có nhất quán hay không. Không cộng các dòng nhật ký nếu chưa xác minh quy tắc tổng hợp cho hồ sơ hóa đơn.
- Quy tắc thanh toán: Xác định Payment Executed có nghĩa là tất toán, ghi sổ chứng từ thanh toán, thực hiện qua ngân hàng hay một mốc nghiệp vụ khác. Dùng nguồn phù hợp với định nghĩa quy trình đã thống nhất.
- Thanh toán trễ: Chỉ tạo sự kiện Late Payment Executed khi Payment Executed xảy ra sau PaymentDueDate. Truy vấn tính rõ sự kiện này, không dựa vào suy luận của ProcessMind.
- Hiệu năng: Giới hạn dữ liệu đọc từ nguồn theo ngày, mã công ty, loại chứng từ và năm tài chính liên quan. Chỉ chọn các cột cần thiết, kiểm tra kế hoạch truy vấn và tạo view trung gian đã được phê duyệt nếu dữ liệu lịch sử lớn.
- Điều kiện tiên quyết: Cần có kết nối trực tiếp SAP HANA, quyền đọc mọi đối tượng được chọn, quyền xem metadata và quyền truy cập dữ liệu liên quan đến Accounts Payable, General Ledger, mua hàng, workflow và thanh toán. Xác nhận đã có các giấy phép SAP, chính sách truy cập cơ sở dữ liệu và phê duyệt bảo vệ dữ liệu cần thiết.
- Bảo mật: Dùng tài khoản kỹ thuật chỉ đọc, bảo vệ dữ liệu nhà cung cấp và thanh toán, đồng thời tuân thủ chính sách của tổ chức về vận chuyển, kiểm toán, che dữ liệu và quản lý thông tin xác thực.
Truy vấn mẫu sql
WITH
invoice_base AS (
SELECT
r.INV_DOC_NO AS InvoiceNumber,
r.COMPANY_CODE AS CompanyCode,
r.FISCAL_YEAR AS FiscalYear,
r.DOCUMENT_TYPE AS DocumentType,
r.VENDOR_NO AS VendorNumber,
r.GROSS_AMOUNT_CC AS AmountInCompanyCodeCurrency,
r.PAYMENT_DUE_DATE AS PaymentDueDate,
r.PURCHASING_DOCUMENT AS PurchasingDocument,
r.CREATED_AT AS InvoiceCreatedAt,
r.CREATED_BY AS InvoiceCreatedBy
FROM [Your RBKP invoice header source] r
WHERE r.CREATED_AT >= '[Start timestamp]'
AND r.CREATED_AT < '[End timestamp]'
AND r.COMPANY_CODE IN ([Company code filter])
AND r.DOCUMENT_TYPE IN ([Document type filter])
),
posted_accounting AS (
SELECT
b.INV_DOC_NO AS InvoiceNumber,
b.COMPANY_CODE AS CompanyCode,
b.FISCAL_YEAR AS FiscalYear,
b.ACCOUNTING_DOCUMENT AS AccountingDocument,
b.POSTING_DATE AS PostingDate,
b.CREATED_AT AS PostedAt,
b.CREATED_BY AS PostedBy,
b.REVERSAL_DOCUMENT AS ReversalDocument,
b.REVERSED_DOCUMENT AS ReversedDocument
FROM [Your BKPF accounting document source] b
WHERE b.CREATED_AT >= '[Start timestamp]'
AND b.CREATED_AT < '[End timestamp]'
AND b.COMPANY_CODE IN ([Company code filter])
),
journal_attributes AS (
SELECT
a.COMPANY_CODE AS CompanyCode,
a.FISCAL_YEAR AS FiscalYear,
a.ACCOUNTING_DOCUMENT AS AccountingDocument,
MAX(a.VENDOR_NO) AS VendorNumber,
SUM(a.AMOUNT_IN_COMPANY_CODE_CURRENCY) AS AmountInCompanyCodeCurrency,
MAX(a.PURCHASING_DOCUMENT) AS PurchasingDocument,
MAX(a.CLEARING_DATE) AS ClearingDate,
MAX(a.CLEARING_DOCUMENT) AS ClearingDocument
FROM [Your ACDOCA universal journal source] a
WHERE a.COMPANY_CODE IN ([Company code filter])
AND a.POSTING_DATE >= '[Start date]'
AND a.POSTING_DATE < '[End date]'
GROUP BY
a.COMPANY_CODE,
a.FISCAL_YEAR,
a.ACCOUNTING_DOCUMENT
),
source_events AS (
SELECT
e.INV_DOC_NO AS InvoiceNumber,
e.COMPANY_CODE AS CompanyCode,
e.FISCAL_YEAR AS FiscalYear,
e.EVENT_TIMESTAMP AS EventTime,
e.EVENT_USER AS UserName,
e.PAYMENT_BLOCK_REASON AS PaymentBlockReason,
e.PURCHASING_DOCUMENT AS PurchasingDocument,
e.VENDOR_NO AS VendorNumber,
e.AMOUNT_IN_COMPANY_CODE_CURRENCY AS AmountInCompanyCodeCurrency,
e.PAYMENT_DUE_DATE AS PaymentDueDate,
e.DOCUMENT_TYPE AS DocumentType,
e.EVENT_TYPE AS SourceEventType
FROM [Your verified invoice event and workflow source] e
WHERE e.EVENT_TIMESTAMP >= '[Start timestamp]'
AND e.EVENT_TIMESTAMP < '[End timestamp]'
AND e.COMPANY_CODE IN ([Company code filter])
),
base_events AS (
SELECT
i.InvoiceNumber,
'Invoice Document Created' AS ActivityName,
i.InvoiceCreatedAt AS EventTime,
i.InvoiceCreatedBy AS UserName,
i.CompanyCode,
COALESCE(i.VendorNumber, j.VendorNumber) AS VendorNumber,
COALESCE(i.AmountInCompanyCodeCurrency, j.AmountInCompanyCodeCurrency) AS AmountInCompanyCodeCurrency,
i.PaymentDueDate,
i.DocumentType,
CAST(NULL AS NVARCHAR(20)) AS PaymentBlockReason,
COALESCE(i.PurchasingDocument, j.PurchasingDocument) AS PurchasingDocument
FROM invoice_base i
LEFT JOIN posted_accounting p
ON p.InvoiceNumber = i.InvoiceNumber
AND p.CompanyCode = i.CompanyCode
AND p.FiscalYear = i.FiscalYear
LEFT JOIN journal_attributes j
ON j.CompanyCode = p.CompanyCode
AND j.FiscalYear = p.FiscalYear
AND j.AccountingDocument = p.AccountingDocument
WHERE i.InvoiceCreatedAt IS NOT NULL
UNION ALL
SELECT
s.InvoiceNumber,
'Invoice Parked' AS ActivityName,
s.EventTime,
s.UserName,
s.CompanyCode,
COALESCE(s.VendorNumber, i.VendorNumber) AS VendorNumber,
COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency) AS AmountInCompanyCodeCurrency,
COALESCE(s.PaymentDueDate, i.PaymentDueDate) AS PaymentDueDate,
COALESCE(s.DocumentType, i.DocumentType) AS DocumentType,
s.PaymentBlockReason,
COALESCE(s.PurchasingDocument, i.PurchasingDocument) AS PurchasingDocument
FROM source_events s
LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PARKED'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Sent For Approval', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'SENT_FOR_APPROVAL'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Approved', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'APPROVED'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Rejected', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'REJECTED'
UNION ALL
SELECT s.InvoiceNumber, 'Invoice Data Updated', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'DATA_UPDATED'
UNION ALL
SELECT s.InvoiceNumber, 'Payment Block Set', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_BLOCK_SET'
UNION ALL
SELECT s.InvoiceNumber, 'Payment Block Removed', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_BLOCK_REMOVED'
UNION ALL
SELECT
i.InvoiceNumber,
'Invoice Posted',
p.PostedAt,
p.PostedBy,
i.CompanyCode,
COALESCE(i.VendorNumber, j.VendorNumber),
COALESCE(i.AmountInCompanyCodeCurrency, j.AmountInCompanyCodeCurrency),
i.PaymentDueDate,
i.DocumentType,
CAST(NULL AS NVARCHAR(20)),
COALESCE(i.PurchasingDocument, j.PurchasingDocument)
FROM invoice_base i
INNER JOIN posted_accounting p ON p.InvoiceNumber = i.InvoiceNumber AND p.CompanyCode = i.CompanyCode AND p.FiscalYear = i.FiscalYear
LEFT JOIN journal_attributes j ON j.CompanyCode = p.CompanyCode AND j.FiscalYear = p.FiscalYear AND j.AccountingDocument = p.AccountingDocument
WHERE p.PostedAt IS NOT NULL
UNION ALL
SELECT s.InvoiceNumber, 'Payment Proposal Created', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_PROPOSAL_CREATED'
UNION ALL
SELECT s.InvoiceNumber, 'Payment Executed', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_EXECUTED'
UNION ALL
SELECT s.InvoiceNumber, 'Late Payment Executed', s.EventTime, s.UserName, s.CompanyCode, COALESCE(s.VendorNumber, i.VendorNumber), COALESCE(s.AmountInCompanyCodeCurrency, i.AmountInCompanyCodeCurrency), COALESCE(s.PaymentDueDate, i.PaymentDueDate), COALESCE(s.DocumentType, i.DocumentType), s.PaymentBlockReason, COALESCE(s.PurchasingDocument, i.PurchasingDocument)
FROM source_events s LEFT JOIN invoice_base i ON i.InvoiceNumber = s.InvoiceNumber AND i.CompanyCode = s.CompanyCode AND i.FiscalYear = s.FiscalYear
WHERE s.SourceEventType = 'PAYMENT_EXECUTED'
AND s.EventTime > CAST(COALESCE(s.PaymentDueDate, i.PaymentDueDate) AS TIMESTAMP)
UNION ALL
SELECT
i.InvoiceNumber,
'Invoice Reversed',
p.ReversalEventAt,
p.ReversalUser,
i.CompanyCode,
COALESCE(i.VendorNumber, j.VendorNumber),
COALESCE(i.AmountInCompanyCodeCurrency, j.AmountInCompanyCodeCurrency),
i.PaymentDueDate,
i.DocumentType,
CAST(NULL AS NVARCHAR(20)),
COALESCE(i.PurchasingDocument, j.PurchasingDocument)
FROM invoice_base i
INNER JOIN [Your verified reversal event source] p ON p.INV_DOC_NO = i.InvoiceNumber AND p.COMPANY_CODE = i.CompanyCode AND p.FISCAL_YEAR = i.FiscalYear
LEFT JOIN journal_attributes j ON j.CompanyCode = p.COMPANY_CODE AND j.FiscalYear = p.FISCAL_YEAR AND j.AccountingDocument = p.ACCOUNTING_DOCUMENT
WHERE p.ReversalEventAt IS NOT NULL
)
SELECT
InvoiceNumber,
ActivityName,
EventTime,
UserName,
CompanyCode,
VendorNumber,
AmountInCompanyCodeCurrency,
PaymentDueDate,
DocumentType,
PaymentBlockReason,
PurchasingDocument
FROM base_events
WHERE InvoiceNumber IS NOT NULL
AND EventTime IS NOT NULL
ORDER BY InvoiceNumber, EventTime, ActivityName; Các bước
- Mở trình soạn thảo ABAP: Đăng nhập vào hệ thống SAP S/4HANA. Mở giao dịch
SE38(ABAP Editor). - Tạo chương trình: Nhập tên chương trình mới vào trường Program, chẳng hạn
Z_PM_INVOICE_EXTRACT, rồi nhấn nút 'Create'. Đặt tiêu đề, chọn Type là 'Executable Program' và lưu vào package phù hợp. - Tạo cấu trúc chương trình và màn hình chọn dữ liệu: Trong trình soạn thảo, xác định cấu trúc dữ liệu cho đầu ra nhật ký sự kiện. Sau đó tạo màn hình chọn dữ liệu để người dùng nhập tham số như khoảng ngày ghi nhận hóa đơn, mã công ty và loại chứng từ. Nhờ vậy, chương trình có thể tái sử dụng và linh hoạt hơn.
- Viết logic chọn dữ liệu: Viết các câu lệnh ABAP SQL chính để chọn dữ liệu từ nhiều bảng SAP. Chương trình sẽ lần lượt truy vấn dữ liệu cho từng hoạt động trong số 13 hoạt động bắt buộc.
- Trích xuất dữ liệu tiêu đề và dòng hàng: Với các sự kiện nền tảng như 'Invoice Document Created' và 'Invoice Posted', chọn dữ liệu từ các bảng chính như
RBKP(tiêu đề hóa đơn logistics) vàBKPF(tiêu đề chứng từ kế toán). - Trích xuất dữ liệu chứng từ thay đổi: Với các hoạt động như 'Payment Block Set' và 'Payment Block Removed', truy vấn các bảng chứng từ thay đổi
CDHDR(tiêu đề chứng từ thay đổi) vàCDPOS(các mục chứng từ thay đổi). Bạn cần xác định thay đổi ở các trường cụ thể, chẳng hạnZLSPRtrong bảngBSEG. - Trích xuất dữ liệu thanh toán: Để ghi nhận các hoạt động liên quan đến thanh toán, truy vấn các bảng như
REGUP(các mục đã xử lý của chương trình thanh toán) để lấy đề xuất thanh toán vàBSAK(các mục nhà cung cấp đã tất toán) để lấy khoản thanh toán đã thực hiện. Xác định 'Late Payment Executed' bằng cách so sánh ngày tất toán (AUGDT) với ngày đến hạn ròng (ZFBDT). - Trích xuất dữ liệu workflow: Với các hoạt động phê duyệt, truy vấn các bảng SAP Business Workflow như
SWW_WI2OBJđể liên kết mục workflow với đối tượng hóa đơn. Phần này phụ thuộc nhiều vào cấu hình workflow cụ thể và có thể cần điều chỉnh đáng kể. - Gộp dữ liệu thành nhật ký sự kiện: Định dạng dữ liệu đã chọn cho từng hoạt động theo cùng một cấu trúc bảng nội bộ. Mỗi dòng trong bảng đại diện cho một sự kiện và phải có mã hồ sơ (
InvoiceNumber),ActivityName,EventTimecùng các thuộc tính được đề xuất khác. - Tạo tệp đầu ra: Dùng các câu lệnh ABAP
OPEN DATASET,TRANSFERvàCLOSE DATASETđể ghi nội dung bảng nội bộ cuối cùng vào tệp phẳng trên máy chủ ứng dụng SAP. Nên dùng định dạng CSV (giá trị phân tách bằng dấu phẩy). - Lên lịch và chạy chương trình: Chạy chương trình ở chế độ foreground để kiểm thử (dùng
F8). Khi chạy production, lên lịch dưới dạng background job bằng giao dịchSM36vào giờ thấp điểm để tránh ảnh hưởng hiệu năng hệ thống. - Lấy tệp và tải lên: Dùng giao dịch
AL11để mở thư mục trên máy chủ ứng dụng nơi đã lưu tệp. Tải tệp về máy tính. Đảm bảo tệp dùng mã hóa UTF-8 và đúng định dạng trước khi tải lên công cụ process mining.
Cấu hình
- Khoảng ngày: Chọn khoảng ngày trích xuất cụ thể dựa trên ngày nhập hóa đơn (
RBKP-CPUDT) hoặc ngày ghi sổ (BKPF-BUDAT). Với lần phân tích đầu tiên, nên dùng khoảng 3 đến 6 tháng để kiểm soát lượng dữ liệu. - Mã công ty (BUKRS): Cần lọc theo một hoặc nhiều mã công ty. Trích xuất dữ liệu của mọi mã công ty trong tổ chức lớn có thể khiến thời gian chạy kéo dài và tạo tệp lớn.
- Loại chứng từ (BLART): Lọc theo loại chứng từ phù hợp để chỉ lấy hóa đơn nhà cung cấp. Các loại thường gặp gồm 'RE' (hóa đơn, tổng tiền) và 'KR' (hóa đơn nhà cung cấp). Cách này giúp loại chứng từ không liên quan khỏi phân tích.
- Tài khoản nhà cung cấp (LIFNR): Có thể thêm bộ lọc tùy chọn cho một số mã nhà cung cấp cụ thể, hữu ích khi phân tích có mục tiêu hoặc kiểm thử.
- Cấu hình tệp đầu ra: Chương trình nên có tham số xác định đường dẫn tệp đầu ra trên máy chủ ứng dụng và ký tự phân tách trường, chẳng hạn dấu phẩy hoặc dấu chấm phẩy.
- Điều kiện tiên quyết: Người dùng hoặc tài khoản hệ thống chạy chương trình cần quyền nhà phát triển để tạo và chạy chương trình ABAP (qua
SE38), cùng quyền đọc rộng đối với các bảng FI, MM và Basis, bao gồmBKPF,BSEG,RBKP,RSEG,CDHDR,CDPOSvà các bảng workflow.
Truy vấn mẫu abap
REPORT Z_PM_INVOICE_EXTRACT.
* --- Internal table structure for the final event log
TYPES: BEGIN OF ty_s_event_log,
invoicenumber TYPE char25,
activityname TYPE char50,
eventtime TYPE char19, "YYYY-MM-DD HH:MM:SS
username TYPE sy-uname,
companycode TYPE bukrs,
vendornumber TYPE lifnr,
amountincompanycodecurrency TYPE wrbtr,
paymentduedate TYPE char10, "YYYY-MM-DD
documenttype TYPE blart,
paymentblockreason TYPE char1,
purchasingdocument TYPE ebeln,
END OF ty_s_event_log.
DATA: lt_event_log TYPE STANDARD TABLE OF ty_s_event_log.
DATA: ls_event_log TYPE ty_s_event_log.
* --- Selection Screen for user inputs
PARAMETERS: p_path TYPE string DEFAULT '/usr/sap/tmp/invoice_events.csv'.
SELECT-OPTIONS: s_erdat FOR sy-datum OBLIGATORY, " Entry Date
s_bukrs FOR bkpf-bukrs OBLIGATORY, " Company Code
s_blart FOR bkpf-blart. " Document Type
START-OF-SELECTION.
* --- 1. Invoice Document Created (from Logistics Invoice Verification)
SELECT CONCAT( rbkp~belnr, rbkp~gjahr ) AS invoicenumber,
'Invoice Document Created' AS activityname,
CONCAT( rbkp~cpudt, rbkp~cputm ) AS eventtime,
rbkp~usnam AS username,
rbkp~bukrs AS companycode,
rbkp~lifnr AS vendornumber,
rbkp~rmwwr AS amountincompanycodecurrency,
'' AS paymentduedate,
rbkp~blart AS documenttype,
rbkp~zuonr AS paymentblockreason,
'' AS purchasingdocument
FROM rbkp
INTO TABLE @DATA(lt_created)
WHERE rbkp~cpudt IN @s_erdat
AND rbkp~bukrs IN @s_bukrs
AND rbkp~blart IN @s_blart.
LOOP AT lt_created INTO DATA(ls_created).
ls_event_log-invoicenumber = ls_created-invoicenumber.
ls_event_log-activityname = ls_created-activityname.
ls_event_log-eventtime = |{ ls_created-eventtime(8) } { ls_created-eventtime+8(2) }:{ ls_created-eventtime+10(2) }:{ ls_created-eventtime+12(2) }|.
ls_event_log-username = ls_created-username.
ls_event_log-companycode = ls_created-companycode.
ls_event_log-vendornumber = ls_created-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_created-amountincompanycodecurrency.
ls_event_log-paymentduedate = ''.
ls_event_log-documenttype = ls_created-documenttype.
ls_event_log-paymentblockreason = ''.
ls_event_log-purchasingdocument = ls_created-purchasingdocument.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 2. Invoice Parked (assuming status 'A' or 'B' in RBKP)
SELECT CONCAT( belnr, gjahr ) AS invoicenumber,
'Invoice Parked' AS activityname,
CONCAT( cpudt, cputm ) AS eventtime,
usnam AS username,
bukrs AS companycode,
lifnr AS vendornumber,
rmwwr AS amountincompanycodecurrency,
'' AS paymentduedate,
blart AS documenttype,
'' AS paymentblockreason,
'' AS purchasingdocument
FROM rbkp
INTO TABLE @DATA(lt_parked)
WHERE rbstat IN ('A', 'B')
AND cpudt IN @s_erdat
AND bukrs IN @s_bukrs
AND blart IN @s_blart.
LOOP AT lt_parked INTO DATA(ls_parked).
ls_event_log-invoicenumber = ls_parked-invoicenumber.
ls_event_log-activityname = ls_parked-activityname.
ls_event_log-eventtime = |{ ls_parked-eventtime(8) } { ls_parked-eventtime+8(2) }:{ ls_parked-eventtime+10(2) }:{ ls_parked-eventtime+12(2) }|.
ls_event_log-username = ls_parked-username.
ls_event_log-companycode = ls_parked-companycode.
ls_event_log-vendornumber = ls_parked-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_parked-amountincompanycodecurrency.
ls_event_log-paymentduedate = ''.
ls_event_log-documenttype = ls_parked-documenttype.
ls_event_log-paymentblockreason = ''.
ls_event_log-purchasingdocument = ''.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 3, 4, 5. Sent For Approval, Approved, Rejected (Placeholder logic, needs adaptation)
* --- This logic is a generic template for SAP Business Workflow.
* --- Your implementation will vary. You must identify the correct workflow tasks.
SELECT obj.instid, wi.wi_cd, wi.wi_ct, wi.wi_stat, wi.wi_aagent
FROM sww_wi2obj AS obj
JOIN swwlog AS wi ON obj~instid = wi~wi_id
INTO TABLE @DATA(lt_workflow)
WHERE obj~typeid = 'BUS2081' " Business Object for Incoming Invoice
AND obj~catid = 'BO'
AND wi~wi_cd IN s_erdat.
LOOP AT lt_workflow INTO DATA(ls_workflow).
* --- This is a placeholder, adapt task IDs and logic
CASE ls_workflow-wi_stat.
WHEN 'STARTED'.
ls_event_log-activityname = 'Invoice Sent For Approval'.
WHEN 'COMPLETED'.
ls_event_log-activityname = 'Invoice Approved'.
WHEN 'CANCELLED'.
ls_event_log-activityname = 'Invoice Rejected'.
WHEN OTHERS.
CONTINUE.
ENDCASE.
* --- Code to get invoice details based on ls_workflow-instid needed here
* --- ... appending to lt_event_log ...
ENDLOOP.
* --- 6, 7, 8. Payment Block Set/Removed, Data Updated (from Change Docs)
SELECT h~objectid, h~username, h~udate, h~utime, p~fname, p~value_new, p~value_old
FROM cdhdr AS h
JOIN cdpos AS p ON h~objectclas = p~objectclas AND h~objectid = p~objectid AND h~changenr = p~changenr
INTO TABLE @DATA(lt_changes)
WHERE h~objectclas = 'BELEGV'
AND h~udate IN s_erdat.
LOOP AT lt_changes INTO DATA(ls_change).
ls_event_log-invoicenumber = |{ ls_change-objectid+10(10) }{ ls_change-objectid(4) }|.
ls_event_log-username = ls_change-username.
ls_event_log-eventtime = |{ ls_change-udate } { ls_change-utime(2) }:{ ls_change-utime+2(2) }:{ ls_change-utime+4(2) }|.
IF ls_change-fname = 'ZLSPR'. " Payment Block
IF ls_change-value_old IS INITIAL AND ls_change-value_new IS NOT INITIAL.
ls_event_log-activityname = 'Payment Block Set'.
ls_event_log-paymentblockreason = ls_change-value_new.
ELSEIF ls_change-value_old IS NOT INITIAL AND ls_change-value_new IS INITIAL.
ls_event_log-activityname = 'Payment Block Removed'.
ls_event_log-paymentblockreason = ''.
ELSE.
CONTINUE.
ENDIF.
ELSE.
ls_event_log-activityname = 'Invoice Data Updated'.
ENDIF.
* --- Need to select other attributes based on invoice number
* --- ... appending to lt_event_log ...
ENDLOOP.
* --- 9. Invoice Posted
SELECT CONCAT( bkpf~belnr, bkpf~gjahr ) AS invoicenumber,
'Invoice Posted' AS activityname,
CONCAT( bkpf~cpudt, bkpf~cputm ) AS eventtime,
bkpf~usnam AS username,
bkpf~bukrs AS companycode,
bseg~lifnr AS vendornumber,
bseg~wrbtr AS amountincompanycodecurrency,
bseg~zfBDT AS paymentduedate,
bkpf~blart AS documenttype,
bseg~zlspr AS paymentblockreason,
bseg~ebeln AS purchasingdocument
FROM bkpf
JOIN bseg ON bkpf~bukrs = bseg~bukrs AND bkpf~belnr = bseg~belnr AND bkpf~gjahr = bseg~gjahr
INTO TABLE @DATA(lt_posted)
WHERE bkpf~cpudt IN @s_erdat
AND bkpf~bukrs IN @s_bukrs
AND bkpf~blart IN @s_blart
AND bseg~koart = 'K'. " Vendor line
LOOP AT lt_posted INTO DATA(ls_posted).
ls_event_log-invoicenumber = ls_posted-invoicenumber.
ls_event_log-activityname = ls_posted-activityname.
ls_event_log-eventtime = |{ ls_posted-eventtime(8) } { ls_posted-eventtime+8(2) }:{ ls_posted-eventtime+10(2) }:{ ls_posted-eventtime+12(2) }|.
ls_event_log-username = ls_posted-username.
ls_event_log-companycode = ls_posted-companycode.
ls_event_log-vendornumber = ls_posted-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_posted-amountincompanycodecurrency.
ls_event_log-paymentduedate = ls_posted-paymentduedate.
ls_event_log-documenttype = ls_posted-documenttype.
ls_event_log-paymentblockreason = ls_posted-paymentblockreason.
ls_event_log-purchasingdocument = ls_posted-purchasingdocument.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 10. Payment Proposal Created
SELECT CONCAT( regup~belnr, regup~gjahr ) AS invoicenumber,
'Payment Proposal Created' AS activityname,
CONCAT( reguh~erfdt, reguh~erfzt ) AS eventtime,
reguh~erfbu AS username,
regup~bukrs AS companycode,
regup~lifnr AS vendornumber,
regup~wrbtr AS amountincompanycodecurrency,
'' AS paymentduedate,
regup~blart AS documenttype,
'' AS paymentblockreason,
'' AS purchasingdocument
FROM regup
JOIN reguh ON regup~laufd = reguh~laufd AND regup~laufi = reguh~laufi
INTO TABLE @DATA(lt_proposal)
WHERE reguh~erfdt IN @s_erdat
AND regup~bukrs IN @s_bukrs.
LOOP AT lt_proposal INTO DATA(ls_proposal).
ls_event_log-invoicenumber = ls_proposal-invoicenumber.
ls_event_log-activityname = ls_proposal-activityname.
ls_event_log-eventtime = |{ ls_proposal-eventtime(8) } { ls_proposal-eventtime+8(2) }:{ ls_proposal-eventtime+10(2) }:{ ls_proposal-eventtime+12(2) }|.
ls_event_log-username = ls_proposal-username.
ls_event_log-companycode = ls_proposal-companycode.
ls_event_log-vendornumber = ls_proposal-vendornumber.
ls_event_log-amountincompanycodecurrency = ls_proposal-amountincompanycodecurrency.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- 11, 12. Payment Executed / Late Payment Executed
SELECT CONCAT( belnr, gjahr ) AS invoicenumber,
augdt,
zfBDT
FROM bsak
INTO TABLE @DATA(lt_cleared)
WHERE augdt IN @s_erdat
AND bukrs IN @s_bukrs.
LOOP AT lt_cleared INTO DATA(ls_cleared).
IF ls_cleared-augdt > ls_cleared-zfbdt.
ls_event_log-activityname = 'Late Payment Executed'.
ELSE.
ls_event_log-activityname = 'Payment Executed'.
ENDIF.
ls_event_log-invoicenumber = ls_cleared-invoicenumber.
ls_event_log-eventtime = |{ ls_cleared-augdt } 00:00:00|.
* --- Need to select other attributes based on invoice number
* --- ... appending to lt_event_log ...
ENDLOOP.
* --- 13. Invoice Reversed
SELECT CONCAT( stblg, stjah ) AS invoicenumber,
'Invoice Reversed' AS activityname,
CONCAT( cpudt, cputm ) AS eventtime,
usnam AS username,
bukrs AS companycode,
'' AS vendornumber,
'' AS amountincompanycodecurrency,
'' AS paymentduedate,
blart AS documenttype,
'' AS paymentblockreason,
'' AS purchasingdocument
FROM bkpf
INTO TABLE @DATA(lt_reversed)
WHERE stblg IS NOT NULL
AND cpudt IN @s_erdat
AND bukrs IN @s_bukrs.
LOOP AT lt_reversed INTO DATA(ls_reversed).
ls_event_log-invoicenumber = ls_reversed-invoicenumber.
ls_event_log-activityname = ls_reversed-activityname.
ls_event_log-eventtime = |{ ls_reversed-eventtime(8) } { ls_reversed-eventtime+8(2) }:{ ls_reversed-eventtime+10(2) }:{ ls_reversed-eventtime+12(2) }|.
ls_event_log-username = ls_reversed-username.
ls_event_log-companycode = ls_reversed-companycode.
APPEND ls_event_log TO lt_event_log.
ENDLOOP.
* --- Write internal table to CSV file
OPEN DATASET p_path FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
MESSAGE 'Error opening file.' TYPE 'E'.
ENDIF.
DATA: lv_line TYPE string.
FIELD-SYMBOLS: <fs_any> TYPE any.
* --- Header row
lv_line = 'InvoiceNumber,ActivityName,EventTime,UserName,CompanyCode,VendorNumber,AmountInCompanyCodeCurrency,PaymentDueDate,DocumentType,PaymentBlockReason,PurchasingDocument'.
TRANSFER lv_line TO p_path.
LOOP AT lt_event_log INTO ls_event_log.
CLEAR lv_line.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE ls_event_log TO <fs_any>.
IF sy-subrc <> 0.
EXIT.
ENDIF.
IF sy-index = 1.
lv_line = <fs_any>.
ELSE.
CONCATENATE lv_line <fs_any> INTO lv_line SEPARATED BY ','.
ENDIF.
ENDDO.
TRANSFER lv_line TO p_path.
ENDLOOP.
CLOSE DATASET p_path.
WRITE: / 'Extraction complete. File saved to:', p_path. Sẵn sàng bắt đầu?
Bắt đầu tối ưu quy trình xử lý hóa đơn ngay hôm nay. Mẫu này là bước đầu tiên giúp bạn cải thiện đáng kể hoạt động vận hành và nâng cao hiệu quả.
Tối ưu quy trình xử lý hóa đơn P2P trên SAP S/4HANA ngay hôm nay
Xác định điểm nghẽn và rút ngắn thời gian xử lý hóa đơn từ 30% trở lên.
Không cần thẻ tín dụng. Thiết lập chỉ trong vài phút.