Data Şablonu: Borç Hesapları Fatura İşleme
Borç Hesapları Fatura İşleme Veri Şablonunuz
- Kapsamlı analiz için önerilen nitelikler
- Etkili takip için kritik süreç aktiviteleri
- Adım adım veri çıkarma rehberi
Hesap Ödemeleri Fatura İşleme Özellikleri
| Ad | Açıklama | ||
|---|---|---|---|
Aktivite ActivityName | Fatura işleme yaşam döngüsünde gerçekleşen belirli bir iş olayı veya adımın adı. | ||
Açıklama Aktivite, Accounts Payable sürecindeki 'Invoice Received', 'Invoice Posted' veya 'Payment Executed' gibi belirgin bir aşama ya da eylemi ifade eder. Bunlar, süreç haritasının yapı taşlarıdır. Aktivitelerin analiz edilmesi, process mining'in temelidir. Süreç akışını görselleştirmenize, yaygın yolları belirlemenize, standart süreçten sapmaları tespit etmenize ve her adımın sıklığını ve süresini ölçmenize yardımcı olur. Belirli bir fatura için bu aktivitelerin sıralaması, o faturanın süreç yolculuğunu oluşturur. Neden önemli Sürecin adımlarını tanımlar; böylece akışın görselleştirilmesi ve analizi, darboğazların belirlenmesi ve yeniden işleme döngülerinin tespiti mümkün olur. Nereden alınır Belge durumu değişiklikleri (örn. BKPF-BSTAT), değişiklik document'ları (CDHDR/CDPOS tabloları) veya workflow log'ları dahil olmak üzere çeşitli kaynaklardan türetilir. Bu genellikle özel bir extraction logic'i gerektirir. Örnekler Fatura AlındıFatura OnaylandıÖdeme GerçekleştirildiFatura Ödeme İçin Bloke Edildi | |||
Event Zamanı EventTime | Aktivitenin gerçekleştiği tam tarih ve saat. | ||
Açıklama Event Time, her aktiviteyle ilişkili zaman damgasıdır (timestamp) ve bir fatura için olayların kronolojik sırasını sağlar. Süreç akışını anlamak ve zamana dayalı analizler yapmak için kritiktir. Analizde Event Time; aktiviteleri doğru sıraya koymak, adımlar arasındaki çevrim sürelerini hesaplamak, bekleme sürelerini tespit etmek ve farklı dönemlere göre (ör. ay bazında) performansı incelemek için kullanılır. Süreye dayalı tüm KPI'ların temelidir. Neden önemli Bu zaman damgası, olayları kronolojik olarak sıralamak ve döngü süreleri, işlem süreleri gibi süreç madenciliğinin temeli olan tüm zaman bazlı metrikleri hesaplamak için hayati öneme sahiptir. Nereden alınır SAP tablolarındaki çeşitli tarih/saat alanlarından elde edilir; örneğin Creation Date (BKPF-CPUDT), Posting Date (BKPF-BUDAT), Clearing Date (BSAK-AUGDT) veya değişiklik günlüğü zaman damgaları (timestamp) (CDHDR-UDATE/UTIME). Örnekler 2023-10-01T09:00:00Z2023-10-05T14:30:15Z2023-10-15T11:21:05Z | |||
Fatura Invoice | Fatura belgesi için benzersiz tanımlayıcı; Accounts Payable sürecinde birincil case ID olarak kullanılır. | ||
Açıklama Fatura, alımdan ödemeye tüm ilgili aktiviteleri birbirine bağlayan merkezi nesnedir. SAP S/4HANA'da bu genellikle Şirket Kodu (BUKRS), benzersiz Belge Numarası (BELNR) ve Mali Yıl (GJAHR) bileşiminden oluşan bileşik bir anahtardır. Analizi faturayı baz alarak yapmak, fatura yaşam döngüsüne uçtan uca bir bakış sağlar. Bu; toplam çevrim süresi gibi temel metriklerin hesaplanması, tekil faturalar için darboğazların belirlenmesi ve bir faturanın süreç içinde izleyebileceği farklı yolların anlaşılması için kritiktir. Neden önemli Her faturanın yolculuğunu benzersiz biçimde tanımlar; tam yaşam döngüsünü izlemeyi ve vaka bazında süreç performansını analiz etmeyi mümkün kılar. Nereden alınır Bu, BKPF (Muhasebe Belgesi Başlığı) veya RBKP (Belge Başlığı: Fatura Alımı) tablolarından BUKRS, BELNR ve GJAHR alanları kullanılarak türetilen bileşik bir anahtardır. Örnekler 1000-1900000001-20231710-1900000002-20232000-5100000003-2024 | |||
Kaynak Sistem SourceSystem | Verinin çekildiği sistem. | ||
Açıklama Bu öznitelik, süreç verisinin kaynağını belirtir. Bu görünüm için değer genellikle 'SAP S/4HANA' olacaktır. Birden fazla ERP veya entegre sistemin olduğu ortamlarda, bu alan veri geçmişi (data lineage) ve ayrımı (segregation) için hayati önem taşır. Analizin doğru veri seti üzerinde yapılmasını sağlar ve veri kalitesi sorunlarını kaynağına kadar izleyerek teşhis etmeye yardımcı olur. Neden önemli Verinin kaynağını belirtir; veri yönetişimi, sorun giderme ve çok sistemli ortamlarda kritik öneme sahiptir. Nereden alınır Bu, genellikle veri çekim (data extraction) sürecinde veri setinin kaynağını etiketlemek için eklenen statik bir değerdir. Örnekler SAP S/4HANASAP ECC 6.0S4H_PROD_100 | |||
Son Veri Güncellemesi LastDataUpdate | Bu kaydın verilerinin kaynak sistemden en son ne zaman yenilendiğini gösteren zaman damgası. | ||
Açıklama Bu öznitelik, SAP S/4HANA'dan yapılan en son veri çekiminin (data extraction) veya güncellemesinin tarih ve saatini gösterir. Analiz edilen verinin güncelliğini anlamak için kritik olan bir meta veri (metadata) alanıdır. Bu bilgi, kullanıcıların süreç analizinin ne kadar güncel olduğunu bilmeleri açısından önemlidir. Veri gecikmesi (data latency) ile ilgili beklentileri yönetmeye yardımcı olur ve veri yenilemelerini planlamak ve veri bütünlüğünü sağlamak için hayati önem taşır. Neden önemli Verinin ne kadar güncel olduğunu gösterir; kullanıcıların süreç analizlerinin güncellik düzeyini bilmelerini sağlar. Nereden alınır Bu değer, kaynak sistemden veri çekimi sırasında oluşturularak her kaydın üzerine işlenir. Örnekler 2024-05-20T04:00:00Z2024-05-21T04:00:00Z | |||
Fatura Tutarı InvoiceAmount | Faturanın orijinal belge para birimindeki toplam brüt tutarı. | ||
Açıklama Bu, tedarikçi tarafından sunulan faturanın toplam değeridir. Herhangi bir kesinti veya indirimden önce, mal veya hizmet maliyetlerini, vergileri ve diğer tüm ücretleri içerir. Fatura Tutarı (Invoice Amount), geniş bir yelpazedeki analizler için kritik bir finansal özniteliktir. Yüksek değerli faturaları önceliklendirmeye, süreç gecikmelerinin finansal etkisini (örn. büyük faturalarda gecikme ücretleri) anlamaya ve süreci bölümlendirmeye (örn. 'Yüksek değerli faturalar farklı bir onay yolunu mu takip ediyor?') yardımcı olur. Ayrıca, olası yinelenen ödemeleri tespit etmek için de elzemdir. Neden önemli Sürece finansal bağlam katar; değer bazlı analiz, yüksek tutarlı faturalara öncelik verme ve finansal etkileri sayısallaştırma imkânı sağlar. Nereden alınır MM faturaları için RBKP-RMWWR (Brüt fatura tutarı) gibi tablolarda bulunur; FI faturaları için BSEG satır kalemlerinden (WRBTR alanı) hesaplanır. Örnekler 1500.00250.7512345.50 | |||
Fatura Vade Tarihi InvoiceDueDate | Faturanın tedarikçiye ödenmesi gereken son gün. | ||
Açıklama Fatura Vade Tarihi, gecikme cezalarından kaçınmak ve tedarikçiyle iyi ilişkiyi korumak için ödemenin yapılması gereken son gündür. Bu tarih, faturanın baz tarihi ve tedarikçiyle mutabık kalınan ödeme şartlarına göre hesaplanır. Bu tarih, 'Payment Compliance & Aging' dashboard'u ve 'Zamanında Ödeme Oranı' KPI'si için esastır. Vade tarihi ile gerçek ödeme tarihini karşılaştırarak, ödemelerin zamanında mı, erken mi yoksa geç mi yapıldığını gösterir; bu da finansal sonuçlar ve tedarikçi ilişkileri üzerinde doğrudan etki yaratır. Neden önemli Bu, zamanında ödeme analizinin temel itici gücüdür ve ödeme performansının ve bunun tedarikçi ilişkileri ve gecikme ücretleri üzerindeki etkisinin ölçülmesini sağlar. Nereden alınır Bu tarih genellikle hesaplanır. Net vade tarihi BSEG-NETDT alanındadır. Aynı zamanda ödeme başlangıç tarihinden (BSEG-ZFBDT) ve ödeme koşullarından (BSEG-ZTERM) türetilebilir. Örnekler 2023-10-312023-11-152024-01-10 | |||
Kullanıcı Adı UserName | Aktiviteyi gerçekleştiren kişinin user ID'si. | ||
Açıklama Bu öznitelik, fatura kaydı, onayı veya ödeme kapatma gibi belirli bir etkinliği gerçekleştiren SAP kullanıcı kimliğini (User ID) kaydeder. Süreç adımlarını bireysel kullanıcılara bağlar. Kullanıcı adına göre analiz yapmak; iş yükü dağılımını anlamak, yüksek performans gösterenleri belirlemek ve ek eğitime ihtiyaç duyabilecek kullanıcıları tespit etmek için elzemdir. Ayrıca, dashboard'larda onay darboğazlarını (approval bottlenecks) analiz etmek için de kilit rol oynar, zira sürecin gecikmesine hangi onaylayıcıların sebep olduğunu belirlemeye yardımcı olur. Neden önemli Aktiviteleri belirli kişilere atayarak kullanıcı performansını, iş yükünü ve görevler ayrılığı politikalarına uyumu analiz etmeyi sağlar. Nereden alınır Genellikle BKPF-USNAM (Giren kişi) gibi başlık tablolarında veya CDHDR-USERNAME (Değiştiren kişi) gibi değişiklik belgesi tablolarında bulunur. Örnekler ABROWNJSMITHAP_AUTOMATION | |||
Satın Alma Sipariş Numarası PurchaseOrderNumber | Varsa, faturayla ilişkili satın alma siparişinin (PO) benzersiz tanımlayıcısı. | ||
Açıklama Bu öznitelik, bir faturayı önceden onaylanmış bir satın alma siparişine (PO) bağlar. Bir PO numarasının varlığı, üçlü eşleştirme sürecinin (Satın Alma Siparişi-Fatura-Mal Kabul) temelini oluşturur. Bu, uyumluluk (compliance) ve verimlilik analizi için hayati bir özniteliktir. Satın alma politikalarına uyumu ölçen 'PO-suz Fatura Yüzdesi' KPI'ını hesaplamak için kullanılır. Aynı zamanda 'Üçlü Eşleştirme Performansı' dashboard'unun da temelidir ve PO destekli faturalar için eşleştirme sürecinin analizine olanak tanır. Neden önemli 3 yönlü eşleştirme verimliliğini analiz etmek ve Satın Alma Siparişsiz (PO'suz) işlenen faturaları belirleyerek tedarik politikalarına uyumu ölçmek için kritik öneme sahiptir. Nereden alınır Fatura satır kalemi tablolarında bulunur; örn. MM faturaları için RSEG-EBELN veya FI faturaları için BSEG-EBELN. Örnekler 45000012344500005678 | |||
Şirket Kodu CompanyCode | Faturanın işlendiği organizasyon birimi. | ||
Açıklama Company Code, dış raporlama için eksiksiz ve bağımsız bir muhasebe setinin tutulabildiği en küçük organizasyon birimidir. AP bağlamında, tedarikçiye karşı borçlu tüzel kişiliği temsil eder. Şirket kodu bazında analiz, organizasyondaki farklı tüzel kişiler arasında süreç performansını karşılaştırmayı sağlar. Böylece hangi birimlerin standart süreçleri izlediğini, hangilerinde verimliliğin düşük, çevrim sürelerinin uzun veya yeniden işleme oranlarının yüksek olduğunu görebilirsiniz. Neden önemli Farklı tüzel kişilikler arasında process performans karşılaştırması yapılmasını sağlayarak bölgesel veya iş birimine özel sorunları ve en iyi uygulamaları belirlemeye yardımcı olur. Nereden alınır Belge başlık tablolarında bulunur; FI faturaları için çoğunlukla BKPF-BUKRS, MM faturaları için RBKP-BUKRS. Örnekler 10001710US01DE01 | |||
Tedarikçi Adı VendorName | Faturayı gönderen tedarikçinin adı. | ||
Açıklama Bu öznitelik, tedarikçinin veya satıcının resmi adını içerir. Fatura belgesinde saklanan Tedarikçi Numarası (Vendor Number) aracılığıyla bağlantılıdır. Tedarikçi analizi, tedarikçi ilişkilerini yönetmek ve belirli tedarikçilere özgü süreç sorunlarını belirlemek için kritik öneme sahiptir. 'Hangi tedarikçiler en çok hatalı fatura gönderiyor?' veya 'Belirli stratejik tedarikçilere ödemelerimizi düzenli ve zamanında yapıyor muyuz?' gibi sorulara yanıt bulmaya yardımcı olabilir. Aynı zamanda, olası yinelenen ödemeleri tespit etmek için fatura numarası ve tutarıyla birlikte temel bir alandır. Neden önemli Tedarikçiye göre süreç performansı analizi yapılmasını sağlar; sorunlu tedarikçileri belirlemeye ve stratejik tedarikçi ilişkilerini etkin biçimde yönetmeye yardımcı olur. Nereden alınır Satıcı ana veri tablosu LFA1'den (NAME1 alanı) elde edilir; BKPF veya RBKP'de yer alan Vendor Number (LIFNR) üzerinden ilişkilendirilir. Örnekler Office Supplies Inc.Global Consulting GroupMachine Parts GmbH | |||
Engelleme Nedeni BlockingReason | Faturanın ödemeye neden bloke edildiğini belirten, bir uyumsuzluğa işaret eden gerekçe. | ||
Açıklama Bir fatura, 3 yollu eşleştirme veya diğer doğrulama adımlarında kontrolü geçemediğinde ödeme için engellenir. Engelleme Nedeni; miktar tutarsızlığı, fiyat farkı veya eksik mal girişi gibi sorunun niteliğini belirtir. Bu özellik, 'Fatura Tutarsızlığı Yeniden İşleme Analizi' dashboard'u için kritik öneme sahiptir. Farklı engelleme nedenlerinin sıklığını analiz etmek, süreç verimsizliklerinin temel nedenlerini belirlemeye yardımcı olur. Örneğin, 'Fiyat farkı' yaygın bir neden ise bu durum, satın alma sistemindeki ana veri sorunlarına işaret edebilir. Neden önemli Fatura tutarsızlıklarının ve yeniden işlemenin kök nedenlerine doğrudan içgörü sağlar; hedefli süreç iyileştirmelerini mümkün kılar. Nereden alınır RSEG gibi fatura satır kalemi tablolarında, SPGR* ile başlayan alanlarda (örn. SPGRP, SPGRQ, SPGRT) saklanır. RBKP_BLOCKED içinde de bulunabilir. Örnekler Fiyat UyuşmazlığıMiktar UyuşmazlığıEksik Mal Girişi | |||
Fatura Belge Türü InvoiceDocumentType | Fatura belgesinin SAP'te nasıl işlendiğini belirleyen sınıflandırma. | ||
Açıklama Belge Türü, SAP'te muhasebe belgelerini sınıflandıran temel bir yapılandırma öğesidir. Örneğin 'KR' genelde tedarikçi faturaları, 'RE' MM faturaları, 'KG' ise tedarikçi alacak dekontları için kullanılır. Bu tür, numara aralığı ve hangi alanların zorunlu olduğu gibi kuralları belirler. Süreç analizinde Belge Türü'ne göre filtrelemek, farklı fatura türlerinin süreç akışlarını karşılaştırmanıza olanak tanır. Örneğin, bir alacak dekontunun onay süreci standart bir faturadan farklı olabilir. Bu, 'Invoice Approval Routing Variants' dashboard'u için faydalıdır. Neden önemli Farklı fatura türlerinin nasıl ele alındığına göre sürecin segmentlere ayrılmasını sağlar; işleme yollarındaki ve çevrim sürelerindeki farklılıkları ortaya çıkarır. Nereden alınır Doğrudan belge header tablosundan, BKPF-BLART alanı. Örnekler KRREKG | |||
Fatura Para Birimi InvoiceCurrency | Fatura tutarının para birimi kodu (örn. USD, EUR). | ||
Açıklama Bu öznitelik, Fatura Tutarı'nın hangi para biriminden olduğunu belirtir. Herhangi bir finansal değer için temel bir bağlam sağlar. Çok uluslu bir organizasyonda, faturaları para birimlerini dikkate almadan analiz etmek yanıltıcı olabilir. Bu alan, tüm tutarları tek bir raporlama para birimine dönüştürerek veya bölgesel finansal faaliyetleri anlamak için analizi para birimine göre bölümlendirerek finansal verilerin doğru şekilde işlenmesine olanak tanır. Neden önemli Fatura Tutarına gerekli bağlamı sağlar; özellikle çok uluslu ortamlarda doğru finansal analiz ve raporlamayı mümkün kılar. Nereden alınır Belge başlık tablolarında bulunur; başlıca BKPF-WAERS veya RBKP-WAERS. Örnekler USDEURGBPJPY | |||
Gecikmiş Ödeme mi? IsLatePayment | Faturanın vadesi geçtikten sonra ödenip ödenmediğini gösteren mantıksal (boolean) bayrak. | ||
Açıklama Bu hesaplanmış öznitelik, bir faturanın ödemesinin resmi vade tarihinden sonra yapılıp yapılmadığını gösteren basit bir doğru/yanlış (true/false) işaretidir. 'Ödeme Kapatma Tarihi' (Clearing Date) ile 'Fatura Vade Tarihi' (Invoice Due Date) karşılaştırılarak elde edilir. Bu işaret, 'Ödeme Uyumluluğu ve Yaşlandırma' dashboard'u ile 'Zamanında Ödeme Oranı' KPI'ı için analizi basitleştirir. Gecikmiş ödeme sayısını saymak, zamanında ödeme yüzdesini hesaplamak ve yüksek oranlarda gecikmiş ödemesi olan tedarikçileri veya şirket kodlarını (company codes) belirlemek için kolay filtreleme ve toplama imkanı sunar. Neden önemli Ödeme koşullarına uyumu doğrudan ölçer, zamanında ödeme KPI hesaplamasını basitleştirir ve düşük ödeme performansına sahip alanları belirlemeye yardımcı olur. Nereden alınır Hesaplanan attribute. Mantık şudur: IF ClearingDate > InvoiceDueDate THEN true ELSE false. Örnekler truefalse | |||
İskonto Yapıldı DiscountTaken | Erken ödeme indiriminin başarıyla uygulanıp uygulanmadığını gösteren mantıksal (boolean) bayrak. | ||
Açıklama Bu öznitelik, faturanın ödendiğinde bir nakit indirimi alınıp alınmadığını gösterir. Borçlar muhasebesi (AP) sürecindeki finansal verimliliği ölçmek için kritik bir bileşendir. Bu işaret, 'Erken Ödeme İndirimi Yakalama Oranı' KPI'ının temelini oluşturur. İndirim olasılığı olan (Ödeme Koşullarına göre) faturaları filtreleyerek ve bu işareti analiz ederek, bir işletme ne kadar tasarruf edildiğini ve kaç tasarruf fırsatının kaçırıldığını kesin olarak hesaplayabilir. Bu, Borçlar Muhasebesi (AP) performansının net, niceliksel bir ölçüsünü sunar. Neden önemli Mevcut erken ödeme indirimlerini yakalama başarısını doğrudan ölçer, bu da şirketin karlılığı üzerinde doğrudan bir etkiye sahiptir. Nereden alınır Ödeme belgesindeki iskonto miktarı alanı (BSEG-SKNTO) sıfırdan büyükse kontrol edilerek türetilir. Örnekler truefalse | |||
İşlem Süresi ProcessingTime | Tek bir aktivitenin süresi. | ||
Açıklama İşleme Süresi (Processing Time) veya aktivite süresi, bir aktivitenin başlangıcı ile bitişi arasında geçen zamandır. Bu metrik, olay günlüğü (event log) verilerinden hesaplanır. Bu hesaplanan ölçüm, 'Activity Duration & Rework Heatmap' dashboard'ı için kritiktir. Sürecin hangi adımlarının en çok zamanı tükettiğini nokta atışı göstermeye yardımcı olur. İşleme sürelerinin analizi; uzun onay adımları veya uzayan uyuşmazlık çözümü faaliyetleri gibi verimsizlikleri ortaya çıkarır ve hedefli iyileştirme çalışmalarına yön verir. Neden önemli Tekil aktivitelerde harcanan süreyi ölçerek, süreçte en çok zaman tüketen adımları ve darboğazları belirlemeye yardımcı olur. Nereden alınır Mevcut aktivitenin EventTime'ı ile aynı fatura için sonraki aktivitenin EventTime'ı arasındaki fark bulunarak hesaplanır. Örnekler P2DT3H4MPT5HP7D | |||
Ödeme Koşulları PaymentTerms | Fatura ödemesi için tedarikçiyle üzerinde anlaşılan koşullar; çoğu zaman erken ödeme indirimlerini de içerir. | ||
Açıklama Ödeme koşulları, vade tarihleri ve olası erken ödeme iskontolarına ilişkin kuralları tanımlar. Örneğin 'Z001' gibi bir koşul, '30 gün içinde ödenir; 10 gün içinde ödenirse %2 iskonto' anlamına gelebilir. Bu nitelik, 'Early Payment Discount Capture Rate' dashboard'ının temelidir. Ödeme koşullarını analiz ederek iskontoya uygun tüm faturaları belirlemek mümkündür. Bunları gerçekte alınan iskontolarla karşılaştırmak, kaçırılan tasarruf fırsatlarını ortaya koyar ve ödeme sürecinin etkinliğini ölçer. Neden önemli Erken ödeme iskontosu fırsatlarını analiz etmek, ödeme sürecinin finansal performansını ölçmek ve kaçırılan tasarrufları belirlemek için kritiktir. Nereden alınır Tedarikçi satır kalemlerinde (BSEG-ZTERM) ya da fatura başlığında (RBKP-ZTERM) bulunur. Örnekler Z0010001NT30 | |||
Otomatikleştirildi mi? IsAutomated | Aktivitenin bir kullanıcı yerine sistem tarafından otomatik olarak yapılıp yapılmadığını gösteren bayrak. | ||
Açıklama Bu boolean öznitelik, insan tarafından başlatılan etkinlikleri sistem görevleri (system jobs), iş akışları (workflows) veya botlar tarafından yürütülenlerden ayırır. Örneğin, otomatik bir ödeme çalıştırması veya sistem tarafından oluşturulan bir fatura kaydı otomatik olarak işaretlenecektir. Bu özniteliği analiz etmek, Borçlar Muhasebesi (Accounts Payable) sürecindeki otomasyon seviyesini anlamaya yardımcı olur. Otomasyon girişimlerinin başarısını ölçmek, otomatik ve manuel adımların verimliliğini karşılaştırmak ve otomasyon için daha fazla fırsat belirlemek için kullanılabilir. Neden önemli Süreçteki otomasyon düzeyini ölçmeye yardımcı olur; otomasyonun etkinliğini analiz etmeyi ve daha fazla iyileştirme fırsatlarını belirlemeyi sağlar. Nereden alınır User Name (örn. 'SAP_SYSTEM' veya 'BATCHUSER' gibi sistem kullanıcı ID'leri) veya otomatikleştirilmiş işlerle ilişkili belirli transaction kodlarına göre türetilir. Örnekler truefalse | |||
Tedarikçi Fatura Numarası VendorInvoiceNumber | Tedarikçinin kendi belgesi üzerinde belirttiği fatura numarası. | ||
Açıklama Bu, tedarikçinin kendi muhasebe sistemindeki referans numarasıdır ve fiziksel veya elektronik fatura belgesinde basılı olarak yer alır. Fatura alımı sırasında manuel olarak girilir veya OCR aracılığıyla yakalanır. Bu alan, özellikle 'Potansiyel Yinelenen Fatura Ödemeleri' dashboard'u için operasyonel amaçlar ve analizler açısından son derece önemlidir. Yinelenenleri tespit etmenin yaygın bir yöntemi, aynı Tedarikçi Adı, Tedarikçi Fatura Numarası ve Fatura Tutarı'nı paylaşan birden fazla dahili fatura belgesini aramaktır. Bir fatura için birincil harici referanstır. Neden önemli Olası mükerrer ödemeleri tespit etmek için kilit bir alan olup, tedarikçilerle iletişimde temel dış referans görevi görür. Nereden alınır Belge başlığındaki 'Reference' alanında, genellikle BKPF-XBLNR'de saklanır. Örnekler INV-2023-9876733401120231015-001 | |||
Temizlenme Tarihi ClearingDate | Ödemenin yapıldığı ve faturanın açık kalemlerden mahsup edilip kapatıldığı tarih. | ||
Açıklama Mahsup Tarihi, faturanın finansal olarak kapatıldığını gösterir. 'Payment Cleared' aktivitesinin gerçekleştiği gündür ve başarılı faturaların çoğunda son adımdır. Bu tarih, gerçek ödeme tarihini Fatura Vade Tarihi ile karşılaştırmak için kullanılır. Bu nedenle 'Zamanında Ödeme Oranı' KPI'sinin hesaplanmasında ve ödeme performansına ilişkin her türlü analizde kritiktir. Ayrıca uçtan uca fatura çevrim süresinin bitiş noktasını da belirler. Neden önemli Bir faturanın nihai ödemesini işaretler; çevrim süresi hesaplamaları için bitiş noktasıdır ve zamanında ödeme analizinin temelini oluşturur. Nereden alınır Mahsup edilmiş kalem tablolarında bulunur; tedarikçiler için örneğin BSAK-AUGDT. Örnekler 2023-10-282023-11-142024-01-09 | |||
Hesap Ödemeleri Fatura İşleme Aktiviteleri
| Aktivite | Açıklama | ||
|---|---|---|---|
Fatura Alındı | Bu aktivite, SAP'te bir fatura belgesinin manuel olarak ya da OCR/VIM gibi otomatik bir arayüz üzerinden oluşturulduğunu gösterir. Olay genellikle muhasebe belgesi başlığının oluşturulma tarih ve saatinden yakalanır. | ||
Neden önemli Sürecin başlangıç noktası olarak, bu aktivite uçtan uca fatura Cycle Time'ını hesaplamak ve tüm Borç Hesapları sürecinin verimini ölçmek için esastır. Nereden alınır Bu olay, muhasebe belgesi başlık tablosundan (BKPF), belge oluşturma tarihi (CPUDT) ve saati (CPUTM) kullanılarak alınır. Yakala Fatura belgesi için oluşturma zaman damgasını (BKPF-CPUDT, BKPF-CPUTM) kullanın. Event tipi explicit | |||
Fatura İptal Edildi | Fatura belgesi ters kaydedilerek finansal etkisi fiilen ortadan kaldırılmıştır. Bu, çoğunlukla hatalı kayıtlar veya tedarikçiyle yaşanan anlaşmazlıklar nedeniyle sürecin alternatif bir bitiş durumudur. | ||
Neden önemli İptalleri izlemek; mükerrer gönderimler veya hatalı fatura verileri gibi süreç başarısızlıklarının nedenlerini anlamaya yardımcı olur ve yukarı akış sorunlarına işaret edebilir. Nereden alınır Bu, bir iptal belgesi oluşturulduğunda açıkça kaydedilir. Orijinal belge başlığında (BKPF) iptal belgesi numarası (STBLG) ve iptal nedeni belirtilecektir. Yakala Orijinal belgenin başlığındaki bağlantıdan (BKPF-STBLG) ulaşılan ters kayıt belgesinin kayıt tarihini belirleyin. Event tipi explicit | |||
Fatura Muhasebeleştirildi | Fatura, finansal bir yükümlülük oluşturarak resmi olarak Genel Defter'e kaydedilmiştir. Park edilmiş belge muhasebeleştirilmiş belgeye dönüşür ya da doğrudan muhasebeleştirme yapılır. | ||
Neden önemli Bu kritik bir finansal dönüm noktasıdır. Şirketin ödeme yükümlülüğünü teyit eder ve genellikle ödeme planlaması için bir ön koşuldur. Nereden alınır Bu olay, belge başlığındaki (BKPF) Kayıt Tarihi (Posting Date - BUDAT) ile tanımlanır. Kaydedilmiş bir belgenin belge durumu (BKPF-BSTAT) boştur. Yakala Park edilmemiş belgeler için (BKPF-BSTAT boşsa) kayıt zaman damgasını (BKPF-BUDAT) kullanın. Event tipi explicit | |||
Fatura Ödeme İçin Bloke Edildi | Sistem, faturaya otomatik ya da manuel bir blokaj koymuş ve ödemenin yapılmasını engellemiştir. Bu genellikle fiyat, miktar tutarsızlıkları veya eksik onaylardan kaynaklanır. | ||
Neden önemli Bu, sorunların ve tekrar işleme ihtiyacının önemli bir göstergesidir. Blokaj nedenleri ve sürelerinin analizi, ödeme gecikmelerinin ve süreç verimsizliklerinin temel nedenlerini belirlemeye yardımcı olur. Nereden alınır Bu, muhasebe belgesinin (BSEG tablosu) tedarikçi satır kalemindeki Ödeme Engelleme Anahtarı (Payment Block Key - ZLSPR) alanına kaydedilen açık bir durumdur. Yakala BSEG-ZLSPR alanına bir bloke nedeni girildiğinde, değişiklik belgeleri üzerinden kaydedilir. Event tipi explicit | |||
Fatura Onaylandı | Fatura, workflow içinde gerekli tüm onayları almıştır. Bu adım genellikle faturanın muhasebeleştirilmesi veya ödeme blokelerinin kaldırılmasından önceki son adımdır. | ||
Neden önemli Bu kilit dönüm noktası, onay döngüsünün sonunu işaret eder. Yönlendirme ve onay arasındaki süre, verimlilik için kritik bir ölçüttür. Nereden alınır SAP Business Workflow log'larından bir tamamlama veya son onay adımı olarak alınır. Alternatif olarak, yönlendirme sonrası bir ödeme engelinin kaldırılmasından çıkarılabilir. Yakala SAP workflow log'larından tamamlanma olaylarını çıkarın veya son 'release' olayını tespit edin. Event tipi explicit | |||
Ödeme Gerçekleştirildi | Fatura için ödeme yapılmıştır. Bu, ödeme çalıştırması (payment run) tamamlandığında ve bir ödeme belgesi oluşturulup muhasebeleştirildiğinde kayda alınır. | ||
Neden önemli Bu aktivite, nakit akışı analizinde ve bu tarihin fatura vade tarihiyle karşılaştırılması yoluyla 'Zamanında Ödeme Oranı' KPI'sinin ölçümünde kritik öneme sahiptir. Nereden alınır Bu, faturayı kapatan ödeme belgesinin kayıt tarihinden (posting date) alınır. Ödeme belgesi numarası, fatura satır kaleminin (BSEG) kapatma belgesi alanında (AUGBL) bağlantılıdır. Yakala Fatura satır kalemini mahsup eden ödeme belgesinin kayıt tarihini (BUDAT) belirleyin. Event tipi explicit | |||
Ödeme Onaylandı | Bu aktivite, alt defterde ödeme ile faturanın karşılıklı olarak mahsuplaştırıldığı ve faturanın nihai olarak kapatıldığı anı işaret eder. Bu, sürecin tamamlandığı anlamına gelir. | ||
Neden önemli Sürecin kesin sonu olarak, bu aktivite doğru uçtan uca Cycle Time hesaplaması için kritik öneme sahiptir. Yükümlülüğün yerine getirildiğini doğrular. Nereden alınır Bu, fatura belgesinin (BSEG tablosu) tedarikçi satır kaleminde Ödeme Kapatma Tarihi (Clearing Date - AUGDT) alanının doldurulmasıyla işaretlenen açık bir olaydır. Yakala Fatura kalemindeki mahsup tarihini (BSEG-AUGDT) kullanın. Event tipi explicit | |||
Fatura Onaya Yönlendirildi | Fatura, iş kurallarına göre gerekli onaylar için workflow'a gönderilmiştir. Bu, onay alt sürecinin başlangıcını ifade eder. | ||
Neden önemli Bu aktivite, 'Ortalama Fatura Onay Süresi' KPI'sinin ölçümünün başlangıç noktasıdır ve onay darboğazlarının analizinde kullanılır. Nereden alınır Fatura objesine (örn. BUS2081) bağlı bir workflow instance'ının başlangıcını kaydeden SAP Business Workflow log'larından (SWW* tabloları) alınabilir. Yakala Fatura belgesine bağlı SAP workflow log'larından (ör. SWW_WIHEAD tablosu) başlangıç olaylarını çıkarın. Event tipi explicit | |||
Fatura Park Edildi | Sisteme girilmiş ancak henüz Genel Defter'e kaydedilmemiş bir faturayı ifade eder. Bu, çoğunlukla eksik bir belgenin daha sonra işlenmesi veya onaya sunulması için bilinçli olarak taslak kaydedilmesidir. | ||
Neden önemli Park edilmiş faturaları izlemek, resmi kayıt süreci başlamadan önceki gecikmeleri tespit etmeye ve veri bütünlüğü veya ilk doğrulama sorunlarını belirlemeye yardımcı olur. Nereden alınır Bu durum, muhasebe belgesi başlığındaki belge durumu alanından (park edilmiş belgeler için BKPF-BSTAT = 'V') alınır. İlgili olay, bu durumun ayarlanmasıyla tetiklenir. Yakala BSTAT alanı 'V' (Vor-erfasst/Ön kayıt) olan BKPF tablosuna ait değişiklik belgelerini tespit edin. Event tipi inferred | |||
Fatura Reddedildi | Onay sürecinde bir onaycı faturayı reddetmiştir. Bu işlem genellikle faturayı düzeltme veya açıklama için işleyene geri gönderir. | ||
Neden önemli Reddedilen işlemleri izlemek, onay sürecindeki yeniden işleme döngülerini ortaya çıkarır ve politika uyumluluğu veya hatalı fatura kodlaması ile ilgili sorunları gösterebilir. Nereden alınır Bu, fatura ile ilişkili SAP Business Workflow logları içinde belirli bir sonuç olayı olarak yakalanır. Yakala SAP workflow log'larından 'rejected' durumundaki workflow olaylarını çıkarın. Event tipi explicit | |||
Fatura Vade Tarihi Geçti | Faturanın net vade tarihinin, karşılığında ödeme mahsup edilmeden geçtiğini belirten hesaplanmış bir olay. Bu, gecikmiş veya vadesi geçmiş ödeme durumunu ifade eder. | ||
Neden önemli 'Ödeme Uyumluluğu ve Vade' dashboard'u için temel olan bu aktivite, vadesi geçmiş faturaları proaktif olarak belirlemeye ve yönetmeye, ayrıca gecikmeli ödemelerin temel nedenlerini analiz etmeye yardımcı olur. Nereden alınır Bu, SAP'de açık bir olay değildir. Sistemin mevcut tarihi ile Net Vade Tarihi (BSEG-ZFBDT veya başlangıç tarihi ve ödeme koşullarından hesaplanan) karşılaştırılarak hesaplanır. Yakala Olay timestamp'i fatura net vade tarihinden büyük olduğunda tetiklenen hesaplanmış event. Event tipi calculated | |||
Mal Kabulü Eşleştirildi | Bu aktivite, faturadaki miktar ve tutarların ilgili mal girişi belgesiyle başarıyla eşleştirildiğini gösterir. 3 yollu eşleştirme senaryosunda son doğrulamadır. | ||
Neden önemli Bunu izlemek, 3 yollu eşleştirme sürecindeki verimsizlikleri ve alınan mallar ile tedarikçi tarafından faturalandırılanlar arasındaki tutarsızlıkları tespit etmeye yardımcı olur. Nereden alınır Bu, fatura satır kaleminde bir malzeme belgesi referansının (mal kabul) varlığından çıkarılır ve genellikle satın alma siparişi kalem geçmişi aracılığıyla bağlanır. Yakala Fatura satır kaleminde Mal Girişi belgesi referansı bulunmasına göre (ör. MIRO faturalarında RSEG) çıkarım yapılır. Event tipi inferred | |||
Ödeme Önerisi Oluşturuldu | Fatura, bir ödeme çalıştırmasının (örn. F110) parçası olarak ödeme teklifine dahil edilmiştir. Çalıştırmanın nihai olarak yürütülmesi beklenirken ödeme için sıraya alınmıştır. | ||
Neden önemli Bu aktivite, açık bir yükümlülükten ödemeye hazırlanmakta olan bir kaleme geçişi gösterir; ödeme operasyonlarının verimliliğini analiz etmeye yardımcı olur. Nereden alınır Bu olay, ödeme çalıştırma veri tablolarında, özellikle REGUP (Ödeme Programından İşlenen Kalemler) ve REGUH (Başlık) tablolarında açıkça kaydedilir. Yakala REGUH’de tanımlanan bir ödeme çalışması için faturanın REGUP tablosunda ne zaman göründüğünü belirleyin. Event tipi explicit | |||
Satın Alma Siparişi Eşleştirildi | Bu aktivite, faturanın ilgili satın alma siparişiyle (PO) başarıyla eşleştirildiğini gösterir. Satın almaya dayalı faturalar için 3 yollu eşleştirmenin kritik bir adımıdır. | ||
Neden önemli Bu aktivitenin analizi, eşleştirme sürecinin verimliliğini ölçmeye yardımcı olur ve '3 Yönlü Eşleştirme Performansı' ile 'PO'suz Fatura Yüzdesi' KPI'ları için temel teşkil eder. Nereden alınır Bu, BSEG veya ACDOCA tablosundaki bir fatura satır kaleminde geçerli bir Satın Alma Siparişi numarası (EBELN) ve kalemi (EBELP) bulunduğunda çıkarılır. Yakala Fatura belgesi oluşturulduğunda üzerinde Satınalma Siparişi referansı (BSEG-EBELN) bulunmasına göre çıkarım yapılır. Event tipi inferred | |||
Uyuşmazlık Giderildi | Bu aktivite, muhtemelen ödeme blokesine yol açan bir sorunun incelenip çözüldüğünü gösterir. Bir faturadan ödeme blokesi kaldırıldığında yakalanır. | ||
Neden önemli Bu yeniden işleme döngüsünü takip etmek, 'Fatura Tutarsızlığı Yeniden İşleme Analizi' dashboard'u için çok önemlidir. Hataları düzeltmek için harcanan zamanı ve eforu ölçmeye yardımcı olur. Nereden alınır Bu, ödeme blokajının kaldırıldığını gösteren değişiklik belgelerinden çıkarılır. BSEG-ZLSPR alanı için değişiklik günlüğü (change log) birincil kaynaktır. Yakala ZLSPR alanının bir değerden boş değere getirildiği BSEG tablosuna ait değişiklik belgelerini tespit edin. Event tipi inferred | |||
Veri Çıkarma Rehberleri
Adımlar
- Ön Koşullar ve Erişim: CDS view'ların bulunduğu SAP S/4HANA veritabanı şemasına (genellikle SAPABAP1 vb.) okuma erişimi olan bir kullanıcı hesabınız olmalı. SAP HANA veritabanına bağlanabilen bir SQL istemcisine ihtiyacınız var; SAP HANA Studio, DBeaver veya benzeri sorgu araçları uygundur.
- Temel CDS view'ları belirleyin: Bu çıkarım için ana CDS view'lar şunlardır: I_JournalEntry, I_JournalEntryItem, I_SupplierInvoiceAPI01, I_ChangeDocument, I_WorkflowStatusDetails ve I_PaymentProposalItem. Temel alanlarına aşina olun.
- Sorgu kapsamını tanımlayın: SQL istemcinizi açıp SAP HANA'ya bağlanın. Tam sorguyu çalıştırmadan önce kapsamı belirleyin: doğru kaynak sistem tanımlayıcısı, faturalar için tarih aralığı (CreationDateTime) ve ilgili şirket kodları.
- Ana sorguyu hazırlayın: query bölümünde verilen tam SQL sorgusunu istemcinize yapıştırın. Sorgu, Common Table Expressions (CTE'ler) kullanarak önce temel fatura kümesini seçer, ardından 15 farklı aktiviteyi birleştirip bir event log oluşturur.
- Sorgu parametrelerini ayarlayın: Kopyaladığınız SQL'deki placeholder değişkenlerini bulun. Analiz dönemi için başlangıç ve bitiş tarihlerini '[YYYY-MM-DD]' yerine yazın. Analiz etmek istediğiniz SAP şirket kodlarını '[Your Company Code 1]', '[Your Company Code 2]' satırına ekleyin.
- Çıkarım sorgusunu çalıştırın: Tam SQL sorgusunu çalıştırın. Veri hacmine ve tarih aralığına bağlı olarak işlem birkaç dakikadan birkaç saate sürebilir.
- Ön sonuçları gözden geçirin: Sorgu bittiğinde çıktının ilk birkaç yüz satırını kontrol edin. Veri tutarlılığını doğrulayın, tüm sütunların beklendiği gibi dolduğunu ve farklı ActivityName değerlerinin bulunduğunu kontrol edin.
- Event log'u dışa aktarın: SQL istemcinizden tüm sonucu bir CSV dosyasına aktarın. Karakter sorunlarını önlemek için dosyanın UTF-8 olarak kodlandığından emin olun. Dosyayı açıklayıcı bir adla kaydedin; örneğin, sap_s4hana_ap_event_log.csv.
- Yüklemeye hazırlık: Bir process mining aracına yüklemeden önce, CSV'deki sütun başlıklarının gerekli öznitelik adlarıyla birebir aynı olduğundan emin olun: Invoice, ActivityName, EventTime, SourceSystem, LastDataUpdate, UserName vb.
- Process mining aracına yükleyin: Oluşturduğunuz CSV dosyasını process mining platformunuza yükleyin ve sütunları ilgili case ID, activity ve timestamp alanlarına eşleyin.
Konfigürasyon
- Temel CDS Görünümleri: Veri çekimi, standart S/4HANA CDS Görünümlerinin bir kombinasyonuna dayanır. Başlıca görünümler şunlardır:
- I_JournalEntry & I_JournalEntryItem: Temel finansal belge başlıkları, kalemleri, kayıt detayları ve mahsuplaşma bilgileri için.
- I_SupplierInvoiceAPI01: Satın Alma Siparişi (PO) referansları ve ödeme blokeleri dahil olmak üzere MM (Lojistik) faturaya özgü detaylar için.
- I_ChangeDocument: Ödeme blokesi koyma veya kaldırma gibi değişikliklerin tam zaman damgasını takip etmek için.
- I_WorkflowStatusDetails: Fatura onay iş akışıyla ilgili olayları çıkarmak için.
- I_PaymentProposalItem: Bir faturanın ödeme çalıştırma teklifine ne zaman dahil edildiğini belirlemek için.
- I_Supplier: Veriyi VendorName gibi tedarikçi ana verileriyle zenginleştirmek için.
- Tarih Aralığı Filtrelemesi: Veri hacmini sınırlamak için bir tarih aralığı filtresi uygulamak kritik öneme sahiptir. Sağlanan sorgu, Invoices_Base CTE'sindeki CreationDateTime üzerinde filtreleme yapar. Yönetilebilir bir performans sağlamak için ilk analizde 3-6 aylık bir aralık önerilir.
- Zorunlu Filtreler: Her zaman CompanyCode ile filtreleme yapın. Tüm şirket kodlarındaki veriyi aynı anda analiz etmek son derece yavaş olabilir ve iş açısından anlamlı olmayabilir. Ayrıca, yalnızca tedarikçiyle ilgili belgeleri (örn. 'KR', 'RE') seçmek için JournalEntryType üzerinde filtreleme yapın.
- Ön Koşullar: Sorguyu yürüten veritabanı kullanıcısının, sorguda kullanılan tüm CDS görünümleri ve temel HANA şeması üzerinde SELECT yetkisine sahip olması gerekir. SAP GUI'deki uygulama düzeyi erişimi yeterli değildir.
- Performans Hususları: I_ChangeDocument üzerinde doğrudan sorgular kaynak yoğun olabilir. Sağlanan sorgu, faturaları önce ön filtreleyerek bunu azaltmaya çalışır. Çok büyük veri kümeleri için, veri çekimi işlemini yoğun olmayan saatlerde veya daha küçük tarih aralığı grupları halinde çalıştırmayı düşünün.
a Örnek Sorgu sql
`sql
-- Common Table Expression (CTE) to select the base set of AP Invoices
WITH Invoices_Base AS (
SELECT
I_JournalEntry.CompanyCode,
I_JournalEntry.AccountingDocument,
I_JournalEntry.FiscalYear,
CONCAT(I_JournalEntry.CompanyCode, CONCAT(I_JournalEntry.AccountingDocument, I_JournalEntry.FiscalYear)) AS InvoiceId,
I_JournalEntry.CreationDateTime,
I_JournalEntry.CreatedByUser,
I_JournalEntry.DocumentStatus,
I_JournalEntry.JournalEntryType,
I_JournalEntry.ReversalReferenceJournalEntry,
I_JournalEntry.IsReversed,
I_JournalEntry.ReversalDate,
IJE_ITEM.NetDueDate,
IJE_ITEM.Supplier,
SUP.SupplierName AS VendorName,
IJE_ITEM.AmountInCompanyCodeCurrency AS InvoiceAmount,
MM.PurchaseOrder AS PurchaseOrderNumber,
MM.PaymentBlockingReason
FROM I_JournalEntry
-- Join to get item details like due date and supplier
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON I_JournalEntry.CompanyCode = IJE_ITEM.CompanyCode
AND I_JournalEntry.AccountingDocument = IJE_ITEM.AccountingDocument
AND I_JournalEntry.FiscalYear = IJE_ITEM.FiscalYear
AND IJE_ITEM.IsSupplier = 'X'
-- Join to get vendor name from master data
LEFT JOIN I_Supplier AS SUP
ON IJE_ITEM.Supplier = SUP.Supplier
-- Join to get MM Invoice specific data like PO Number and Payment Block
LEFT JOIN I_SupplierInvoiceAPI01 AS MM
ON I_JournalEntry.AccountingDocument = MM.AccountingDocument
AND I_JournalEntry.CompanyCode = MM.CompanyCode
AND I_JournalEntry.FiscalYear = MM.FiscalYear
WHERE
I_JournalEntry.JournalEntryType IN ('KR', 'RE') -- Standard Vendor Invoice Types
AND I_JournalEntry.CompanyCode IN ('[Your Company Code 1]', '[Your Company Code 2]')
AND I_JournalEntry.CreationDateTime BETWEEN '[YYYY-MM-DD]T00:00:00Z' AND '[YYYY-MM-DD]T23:59:59Z'
)
-- Event: 1. Invoice Received
SELECT
B.InvoiceId AS "Invoice",
'Invoice Received' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
UNION ALL
-- Event: 2. Invoice Parked
SELECT
B.InvoiceId AS "Invoice",
'Invoice Parked' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.DocumentStatus = 'V' -- 'V' stands for Parked
UNION ALL
-- Event: 3. Purchase Order Matched
SELECT
B.InvoiceId AS "Invoice",
'Purchase Order Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PurchaseOrderNumber IS NOT NULL AND B.PurchaseOrderNumber <> ''
UNION ALL
-- Event: 4. Goods Receipt Matched
SELECT
B.InvoiceId AS "Invoice",
'Goods Receipt Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_SupplierInvoiceItemAPI01 AS MM_ITEM
ON B.AccountingDocument = MM_ITEM.AccountingDocument
AND B.FiscalYear = MM_ITEM.FiscalYear
WHERE MM_ITEM.GoodsReceipt IS NOT NULL AND MM_ITEM.GoodsReceipt <> ''
UNION ALL
-- Event: 5. Invoice Blocked For Payment
SELECT
B.InvoiceId AS "Invoice",
'Invoice Blocked For Payment' AS "ActivityName",
B.CreationDateTime AS "EventTime", -- Approximates block time as creation time if blocked on entry
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PaymentBlockingReason IS NOT NULL AND B.PaymentBlockingReason <> ''
UNION ALL
-- Event: 6. Discrepancy Resolved (Payment Block Removed)
SELECT
B.InvoiceId AS "Invoice",
'Discrepancy Resolved' AS "ActivityName",
CD.ChangeTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CD.UserName AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_ChangeDocument AS CD
ON CONCAT(B.CompanyCode, B.AccountingDocument, B.FiscalYear) = CD.ObjectValue
WHERE CD.ChangeDocumentObject = 'INVOICE'
AND CD.TableName = 'RBKP'
AND CD.FieldName = 'ZLSPR' -- Field for Payment Block
AND CD.NewFieldValue = '' -- Block was removed
UNION ALL
-- Event: 7, 8, 9. Workflow Events (Routed, Approved, Rejected)
SELECT
B.InvoiceId AS "Invoice",
CASE WF.WorkflowStatus
WHEN 'READY' THEN 'Invoice Routed For Approval'
WHEN 'APPROVED' THEN 'Invoice Approved'
WHEN 'REJECTED' THEN 'Invoice Rejected'
END AS "ActivityName",
WF.WorkflowStatusChangedDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
WF.WorkflowStatusChangedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_WorkflowStatusDetails AS WF
ON B.InvoiceId = WF.WorkflowScenarioInstance
WHERE WF.WorkflowStatus IN ('READY', 'APPROVED', 'REJECTED')
UNION ALL
-- Event: 10. Invoice Posted
SELECT
B.InvoiceId AS "Invoice",
'Invoice Posted' AS "ActivityName",
JE.PostingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntry AS JE
ON B.AccountingDocument = JE.AccountingDocument
AND B.CompanyCode = JE.CompanyCode
AND B.FiscalYear = JE.FiscalYear
WHERE B.DocumentStatus <> 'V' -- Any status other than Parked is considered Posted for AP
UNION ALL
-- Event: 11. Payment Proposal Created
SELECT
B.InvoiceId AS "Invoice",
'Payment Proposal Created' AS "ActivityName",
PPI.PaymentProposalRunDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
PPI.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_PaymentProposalItem AS PPI
ON B.CompanyCode = PPI.CompanyCode
AND B.AccountingDocument = PPI.AccountingDocument
AND B.FiscalYear = PPI.FiscalYear
UNION ALL
-- Event: 12. Payment Executed
-- This links the invoice to its clearing document, which is the payment document
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Executed' AS "ActivityName",
CLEAR_JE.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CLEAR_JE.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
INNER JOIN I_JournalEntry AS CLEAR_JE
ON IJE_ITEM.ClearingJournalEntry = CLEAR_JE.AccountingDocument
AND IJE_ITEM.CompanyCode = CLEAR_JE.CompanyCode
WHERE IJE_ITEM.ClearingJournalEntry IS NOT NULL AND IJE_ITEM.ClearingJournalEntry <> ''
AND CLEAR_JE.JournalEntryType = 'KZ' -- Vendor Payment Document Type
UNION ALL
-- Event: 13. Invoice Due Date Passed
SELECT
B.InvoiceId AS "Invoice",
'Invoice Due Date Passed' AS "ActivityName",
ADD_DAYS(B.NetDueDate, 1) AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
'SYSTEM' AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE B.NetDueDate < CURRENT_DATE
AND IJE_ITEM.ClearingDate IS NULL -- Invoice is not yet cleared
UNION ALL
-- Event: 14. Payment Cleared
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Cleared' AS "ActivityName",
IJE_ITEM.ClearingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
IJE_ITEM.ChangedByUser AS "UserName", -- User who cleared it
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE IJE_ITEM.ClearingDate IS NOT NULL
UNION ALL
-- Event: 15. Invoice Cancelled
SELECT
B.InvoiceId AS "Invoice",
'Invoice Cancelled' AS "ActivityName",
B.ReversalDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName", -- User who created the original document
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.IsReversed = 'X';
`Adımlar
- Ön Koşullar ve Erişim: CDS view'ların bulunduğu SAP S/4HANA veritabanı şemasına (genellikle SAPABAP1 vb.) okuma erişimi olan bir kullanıcı hesabınız olmalı. SAP HANA veritabanına bağlanabilen bir SQL istemcisine ihtiyacınız var; SAP HANA Studio, DBeaver veya benzeri sorgu araçları uygundur.
- Temel CDS view'ları belirleyin: Bu çıkarım için ana CDS view'lar şunlardır: I_JournalEntry, I_JournalEntryItem, I_SupplierInvoiceAPI01, I_ChangeDocument, I_WorkflowStatusDetails ve I_PaymentProposalItem. Temel alanlarına aşina olun.
- Sorgu kapsamını tanımlayın: SQL istemcinizi açıp SAP HANA'ya bağlanın. Tam sorguyu çalıştırmadan önce kapsamı belirleyin: doğru kaynak sistem tanımlayıcısı, faturalar için tarih aralığı (CreationDateTime) ve ilgili şirket kodları.
- Ana sorguyu hazırlayın: query bölümünde verilen tam SQL sorgusunu istemcinize yapıştırın. Sorgu, Common Table Expressions (CTE'ler) kullanarak önce temel fatura kümesini seçer, ardından 15 farklı aktiviteyi birleştirip bir event log oluşturur.
- Sorgu parametrelerini ayarlayın: Kopyaladığınız SQL'deki placeholder değişkenlerini bulun. Analiz dönemi için başlangıç ve bitiş tarihlerini '[YYYY-MM-DD]' yerine yazın. Analiz etmek istediğiniz SAP şirket kodlarını '[Your Company Code 1]', '[Your Company Code 2]' satırına ekleyin.
- Çıkarım sorgusunu çalıştırın: Tam SQL sorgusunu çalıştırın. Veri hacmine ve tarih aralığına bağlı olarak işlem birkaç dakikadan birkaç saate sürebilir.
- Ön sonuçları gözden geçirin: Sorgu bittiğinde çıktının ilk birkaç yüz satırını kontrol edin. Veri tutarlılığını doğrulayın, tüm sütunların beklendiği gibi dolduğunu ve farklı ActivityName değerlerinin bulunduğunu kontrol edin.
- Event log'u dışa aktarın: SQL istemcinizden tüm sonucu bir CSV dosyasına aktarın. Karakter sorunlarını önlemek için dosyanın UTF-8 olarak kodlandığından emin olun. Dosyayı açıklayıcı bir adla kaydedin; örneğin, sap_s4hana_ap_event_log.csv.
- Yüklemeye hazırlık: Bir process mining aracına yüklemeden önce, CSV'deki sütun başlıklarının gerekli öznitelik adlarıyla birebir aynı olduğundan emin olun: Invoice, ActivityName, EventTime, SourceSystem, LastDataUpdate, UserName vb.
- Process mining aracına yükleyin: Oluşturduğunuz CSV dosyasını process mining platformunuza yükleyin ve sütunları ilgili case ID, activity ve timestamp alanlarına eşleyin.
Konfigürasyon
- Temel CDS Görünümleri: Veri çekimi, standart S/4HANA CDS Görünümlerinin bir kombinasyonuna dayanır. Başlıca görünümler şunlardır:
- I_JournalEntry & I_JournalEntryItem: Temel finansal belge başlıkları, kalemleri, kayıt detayları ve mahsuplaşma bilgileri için.
- I_SupplierInvoiceAPI01: Satın Alma Siparişi (PO) referansları ve ödeme blokeleri dahil olmak üzere MM (Lojistik) faturaya özgü detaylar için.
- I_ChangeDocument: Ödeme blokesi koyma veya kaldırma gibi değişikliklerin tam zaman damgasını takip etmek için.
- I_WorkflowStatusDetails: Fatura onay iş akışıyla ilgili olayları çıkarmak için.
- I_PaymentProposalItem: Bir faturanın ödeme çalıştırma teklifine ne zaman dahil edildiğini belirlemek için.
- I_Supplier: Veriyi VendorName gibi tedarikçi ana verileriyle zenginleştirmek için.
- Tarih Aralığı Filtrelemesi: Veri hacmini sınırlamak için bir tarih aralığı filtresi uygulamak kritik öneme sahiptir. Sağlanan sorgu, Invoices_Base CTE'sindeki CreationDateTime üzerinde filtreleme yapar. Yönetilebilir bir performans sağlamak için ilk analizde 3-6 aylık bir aralık önerilir.
- Zorunlu Filtreler: Her zaman CompanyCode ile filtreleme yapın. Tüm şirket kodlarındaki veriyi aynı anda analiz etmek son derece yavaş olabilir ve iş açısından anlamlı olmayabilir. Ayrıca, yalnızca tedarikçiyle ilgili belgeleri (örn. 'KR', 'RE') seçmek için JournalEntryType üzerinde filtreleme yapın.
- Ön Koşullar: Sorguyu yürüten veritabanı kullanıcısının, sorguda kullanılan tüm CDS görünümleri ve temel HANA şeması üzerinde SELECT yetkisine sahip olması gerekir. SAP GUI'deki uygulama düzeyi erişimi yeterli değildir.
- Performans Hususları: I_ChangeDocument üzerinde doğrudan sorgular kaynak yoğun olabilir. Sağlanan sorgu, faturaları önce ön filtreleyerek bunu azaltmaya çalışır. Çok büyük veri kümeleri için, veri çekimi işlemini yoğun olmayan saatlerde veya daha küçük tarih aralığı grupları halinde çalıştırmayı düşünün.
a Örnek Sorgu sql
`sql
-- Common Table Expression (CTE) to select the base set of AP Invoices
WITH Invoices_Base AS (
SELECT
I_JournalEntry.CompanyCode,
I_JournalEntry.AccountingDocument,
I_JournalEntry.FiscalYear,
CONCAT(I_JournalEntry.CompanyCode, CONCAT(I_JournalEntry.AccountingDocument, I_JournalEntry.FiscalYear)) AS InvoiceId,
I_JournalEntry.CreationDateTime,
I_JournalEntry.CreatedByUser,
I_JournalEntry.DocumentStatus,
I_JournalEntry.JournalEntryType,
I_JournalEntry.ReversalReferenceJournalEntry,
I_JournalEntry.IsReversed,
I_JournalEntry.ReversalDate,
IJE_ITEM.NetDueDate,
IJE_ITEM.Supplier,
SUP.SupplierName AS VendorName,
IJE_ITEM.AmountInCompanyCodeCurrency AS InvoiceAmount,
MM.PurchaseOrder AS PurchaseOrderNumber,
MM.PaymentBlockingReason
FROM I_JournalEntry
-- Join to get item details like due date and supplier
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON I_JournalEntry.CompanyCode = IJE_ITEM.CompanyCode
AND I_JournalEntry.AccountingDocument = IJE_ITEM.AccountingDocument
AND I_JournalEntry.FiscalYear = IJE_ITEM.FiscalYear
AND IJE_ITEM.IsSupplier = 'X'
-- Join to get vendor name from master data
LEFT JOIN I_Supplier AS SUP
ON IJE_ITEM.Supplier = SUP.Supplier
-- Join to get MM Invoice specific data like PO Number and Payment Block
LEFT JOIN I_SupplierInvoiceAPI01 AS MM
ON I_JournalEntry.AccountingDocument = MM.AccountingDocument
AND I_JournalEntry.CompanyCode = MM.CompanyCode
AND I_JournalEntry.FiscalYear = MM.FiscalYear
WHERE
I_JournalEntry.JournalEntryType IN ('KR', 'RE') -- Standard Vendor Invoice Types
AND I_JournalEntry.CompanyCode IN ('[Your Company Code 1]', '[Your Company Code 2]')
AND I_JournalEntry.CreationDateTime BETWEEN '[YYYY-MM-DD]T00:00:00Z' AND '[YYYY-MM-DD]T23:59:59Z'
)
-- Event: 1. Invoice Received
SELECT
B.InvoiceId AS "Invoice",
'Invoice Received' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
UNION ALL
-- Event: 2. Invoice Parked
SELECT
B.InvoiceId AS "Invoice",
'Invoice Parked' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.DocumentStatus = 'V' -- 'V' stands for Parked
UNION ALL
-- Event: 3. Purchase Order Matched
SELECT
B.InvoiceId AS "Invoice",
'Purchase Order Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PurchaseOrderNumber IS NOT NULL AND B.PurchaseOrderNumber <> ''
UNION ALL
-- Event: 4. Goods Receipt Matched
SELECT
B.InvoiceId AS "Invoice",
'Goods Receipt Matched' AS "ActivityName",
B.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_SupplierInvoiceItemAPI01 AS MM_ITEM
ON B.AccountingDocument = MM_ITEM.AccountingDocument
AND B.FiscalYear = MM_ITEM.FiscalYear
WHERE MM_ITEM.GoodsReceipt IS NOT NULL AND MM_ITEM.GoodsReceipt <> ''
UNION ALL
-- Event: 5. Invoice Blocked For Payment
SELECT
B.InvoiceId AS "Invoice",
'Invoice Blocked For Payment' AS "ActivityName",
B.CreationDateTime AS "EventTime", -- Approximates block time as creation time if blocked on entry
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.PaymentBlockingReason IS NOT NULL AND B.PaymentBlockingReason <> ''
UNION ALL
-- Event: 6. Discrepancy Resolved (Payment Block Removed)
SELECT
B.InvoiceId AS "Invoice",
'Discrepancy Resolved' AS "ActivityName",
CD.ChangeTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CD.UserName AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_ChangeDocument AS CD
ON CONCAT(B.CompanyCode, B.AccountingDocument, B.FiscalYear) = CD.ObjectValue
WHERE CD.ChangeDocumentObject = 'INVOICE'
AND CD.TableName = 'RBKP'
AND CD.FieldName = 'ZLSPR' -- Field for Payment Block
AND CD.NewFieldValue = '' -- Block was removed
UNION ALL
-- Event: 7, 8, 9. Workflow Events (Routed, Approved, Rejected)
SELECT
B.InvoiceId AS "Invoice",
CASE WF.WorkflowStatus
WHEN 'READY' THEN 'Invoice Routed For Approval'
WHEN 'APPROVED' THEN 'Invoice Approved'
WHEN 'REJECTED' THEN 'Invoice Rejected'
END AS "ActivityName",
WF.WorkflowStatusChangedDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
WF.WorkflowStatusChangedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_WorkflowStatusDetails AS WF
ON B.InvoiceId = WF.WorkflowScenarioInstance
WHERE WF.WorkflowStatus IN ('READY', 'APPROVED', 'REJECTED')
UNION ALL
-- Event: 10. Invoice Posted
SELECT
B.InvoiceId AS "Invoice",
'Invoice Posted' AS "ActivityName",
JE.PostingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntry AS JE
ON B.AccountingDocument = JE.AccountingDocument
AND B.CompanyCode = JE.CompanyCode
AND B.FiscalYear = JE.FiscalYear
WHERE B.DocumentStatus <> 'V' -- Any status other than Parked is considered Posted for AP
UNION ALL
-- Event: 11. Payment Proposal Created
SELECT
B.InvoiceId AS "Invoice",
'Payment Proposal Created' AS "ActivityName",
PPI.PaymentProposalRunDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
PPI.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_PaymentProposalItem AS PPI
ON B.CompanyCode = PPI.CompanyCode
AND B.AccountingDocument = PPI.AccountingDocument
AND B.FiscalYear = PPI.FiscalYear
UNION ALL
-- Event: 12. Payment Executed
-- This links the invoice to its clearing document, which is the payment document
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Executed' AS "ActivityName",
CLEAR_JE.CreationDateTime AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
CLEAR_JE.CreatedByUser AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
INNER JOIN I_JournalEntry AS CLEAR_JE
ON IJE_ITEM.ClearingJournalEntry = CLEAR_JE.AccountingDocument
AND IJE_ITEM.CompanyCode = CLEAR_JE.CompanyCode
WHERE IJE_ITEM.ClearingJournalEntry IS NOT NULL AND IJE_ITEM.ClearingJournalEntry <> ''
AND CLEAR_JE.JournalEntryType = 'KZ' -- Vendor Payment Document Type
UNION ALL
-- Event: 13. Invoice Due Date Passed
SELECT
B.InvoiceId AS "Invoice",
'Invoice Due Date Passed' AS "ActivityName",
ADD_DAYS(B.NetDueDate, 1) AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
'SYSTEM' AS "UserName",
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
LEFT JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE B.NetDueDate < CURRENT_DATE
AND IJE_ITEM.ClearingDate IS NULL -- Invoice is not yet cleared
UNION ALL
-- Event: 14. Payment Cleared
SELECT DISTINCT
B.InvoiceId AS "Invoice",
'Payment Cleared' AS "ActivityName",
IJE_ITEM.ClearingDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
IJE_ITEM.ChangedByUser AS "UserName", -- User who cleared it
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
INNER JOIN I_JournalEntryItem AS IJE_ITEM
ON B.CompanyCode = IJE_ITEM.CompanyCode
AND B.AccountingDocument = IJE_ITEM.AccountingDocument
AND B.FiscalYear = IJE_ITEM.FiscalYear
WHERE IJE_ITEM.ClearingDate IS NOT NULL
UNION ALL
-- Event: 15. Invoice Cancelled
SELECT
B.InvoiceId AS "Invoice",
'Invoice Cancelled' AS "ActivityName",
B.ReversalDate AS "EventTime",
'SAP_S4HANA' AS "SourceSystem",
CURRENT_UTCTIMESTAMP AS "LastDataUpdate",
B.CreatedByUser AS "UserName", -- User who created the original document
B.CompanyCode AS "CompanyCode",
B.VendorName AS "VendorName",
B.InvoiceAmount AS "InvoiceAmount",
B.PurchaseOrderNumber AS "PurchaseOrderNumber",
B.NetDueDate AS "InvoiceDueDate"
FROM Invoices_Base B
WHERE B.IsReversed = 'X';
`Adımlar
- Şartname ve Tasarım: Kodlamadan önce, gerekli 15 aktivitenin her biri için kesin tetikleme koşullarını ve veri alanlarını doğrulamak üzere iş analistleriyle iş birliği yaparak doğrulayın. Kapsama dahil edilecek ilgili SAP tablolarını, belge türlerini (örn., 'KR', 'RE') ve şirket kodlarını belirleyin.
- ABAP Programı Oluşturma: SE38 işlem kodunu kullanarak ABAP Editor'ü başlatın. Örneğin, Z_PM_AP_INVOICE_EXTRACT adında yeni bir yürütülebilir program oluşturun. Açıklayıcı bir başlık verin ve uygulamayı 'Financial Accounting' olarak ayarlayın.
- Seçim Ekranını Tanımlama: Programda, kullanıcıların çıkarma tarih aralığını (fatura oluşturma tarihi için), hedef Company Codes (BUKRS) ve ilgili fatura Document Types (BLART) belirleyebileceği bir seçim ekranı (PARAMETERS ve SELECT-OPTIONS anahtar kelimelerini kullanarak) tanımlayın. Ayrıca uygulama sunucusundaki çıkış dosyası yolu için bir parametre ekleyin.
- Veri Tanımlamaları: Tüm gerekli ve önerilen öznitelikleri içeren, nihai event log formatıyla (örn., TY_EVENT_LOG) eşleşen dahili bir tablo yapısı tanımlayın. BKPF, BSEG, RBKP, RSEG, CDHDR, CDPOS ve REGUH gibi çeşitli SAP kaynak tablolarından alınacak verileri tutmak üzere dahili tablolar bildirin.
- Ana Veri Seçimi: Kullanıcının seçim ekranı kriterlerine göre RBKP (Lojistik Faturaları) ve BKPF (Finansal Faturalar) tablolarından birincil fatura kümesini seçerek çıkarma mantığını başlatın. Sonraki veri aramalarında kullanılmak üzere bu birincil fatura anahtarlarını dahili bir tabloda saklayın.
- Aktiviteleri Sırasıyla Çıkarma: Ana kümedeki her fatura için, her iş aktivitesi için timestamp'leri ve ayrıntıları bulmak amacıyla bir dizi sorgulama yapın. Örneğin, ödeme blokajı değişiklikleri için CDHDR ve CDPOS'u sorgulayın, ödeme çalıştırma verileri için REGUH ve REGUP'u sorgulayın ve ters kayıt belgelerinin ayrıntıları için BKPF'yi sorgulayın. Her bulunan aktivite için nihai event log tablosuna yeni bir kayıt ekleyin.
- Hesaplamaya Dayalı Olayların Mantığı: Bir tablo alanında doğrudan saklanmayan aktiviteler için ABAP mantığını uygulayın. 'Fatura Son Ödeme Tarihi Geçti' olayı için, fatura son ödeme tarihini (BSEG-ZFBDT + ödeme koşulları) ve temizleme tarihini (BSEG-AUGDT) kullanın. Eğer temizleme tarihi son ödeme tarihinden daha sonraysa, timestamp'i son ödeme tarihi olarak ayarlanmış yeni bir olay kaydı oluşturun.
- Veri Dönüşümü ve Zenginleştirme: Her aktivite için veri toplarken, gerekli tüm öznitelikleri doldurun. Bu adımlar, LFA1 tablosundan satıcı adlarını çekmeyi, tarih ve saatleri tek bir timestamp dizisine (CONCATENATE...INTO...) dönüştürmeyi ve SourceSystem değerini belirlemeyi içerir.
- Çıktı Dosyası Oluşturma: Tüm faturalar ve bunlara karşılık gelen aktiviteler işlenip nihai dahili tabloda toplandıktan sonra, OPEN DATASET, LOOP AT ... TRANSFER ve CLOSE DATASET ifadelerini kullanarak verileri seçim ekranında belirtilen uygulama sunucusu yolundaki bir dosyaya yazın.
- İndirme ve Yükleme için Hazırlık: Oluşturulan dosyayı uygulama sunucusundan yerel makinenize indirmek için CG3Y işlem kodunu kullanın. Dosyanın UTF-8 kodlamalı CSV formatında kaydedildiğinden emin olun. Process Mining aracına yüklemeden önce sütun başlıklarının gerekli özniteliklerle (Invoice, ActivityName, EventTime vb.) eşleştiğini doğrulayın.
Konfigürasyon
- Tarih Aralığı: Fatura oluşturma tarihi (BKPF-CPUDT veya RBKP-CPUDT) için P_CPUDT seçim alanını tanımlayın. İlk analiz için 6-12 aylık bir veri aralığı önerilir.
- Şirket Kodu (P_BUKRS): Belirli şirket kodlarını filtrelemek için zorunlu bir SELECT-OPTIONS parametresi. Kesinlikle gerekli olmadıkça tüm şirket kodlarının aynı anda işlenmesi önerilmez.
- Fatura Belge Türü (P_BLART): İlgili fatura belge türlerini filtrelemek için bir SELECT-OPTIONS parametresi. Yaygın türler arasında 'KR' (Satıcı Faturası), 'KG' (Satıcı Kredi Notu), 'RE' (Lojistik Fatura Doğrulama) bulunur.
- Çalıştırma Modu: Program, büyük veri hacimleri için ön plan diyalog sürecinde zaman aşımını önlemek amacıyla bir arka plan işi (SM36/SM37) olarak çalıştırılmalıdır. Yoğun olmayan saatlerde çalışacak şekilde planlayın.
- Çıktı Dosya Yolu: SAP uygulama sunucusunda dosya yolunu ve adını (örn. /tmp/ dizininde) belirtmek için bir PARAMETER. Dosya indirilmeden önce buraya yazılır.
- Ön Koşullar: Raporu çalıştıran kullanıcının FI, CO ve MM tablolarından (BKPF, BSEG, RBKP, RSEG, LFA1), belge değiştirme tablolarından (CDHDR, CDPOS) ve workflow tablolarından okuma yetkisi olmalıdır. Ayrıca, uygulama sunucusuna dosya yazmak için S_DATASET yetkilendirme nesnesi gereklidir.
a Örnek Sorgu abap
`abap
*&---------------------------------------------------------------------*
*& Report Z_PM_AP_INVOICE_EXTRACT
*&---------------------------------------------------------------------*
*& This report extracts Accounts Payable invoice lifecycle events for
*& process mining analysis.
*&---------------------------------------------------------------------*
REPORT z_pm_ap_invoice_extract.
*&---------------------------------------------------------------------*
*& Data Structures
*&---------------------------------------------------------------------*
TYPES: BEGIN OF ty_event_log,
invoice TYPE belnr_d,
activityname TYPE string,
eventtime TYPE string,
sourcesystem TYPE logsys,
lastdataupdate TYPE string,
username TYPE uname,
companycode TYPE bukrs,
vendorname TYPE name1_gp,
invoiceamount TYPE wrbtr,
purchaseordernumber TYPE ebeln,
invoiceduedate TYPE d,
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
DATA: gv_system_id TYPE logsys.
DATA: gv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_bukrs FOR bkpf-bukrs OBLIGATORY,
s_cpudt FOR bkpf-cpudt OBLIGATORY DEFAULT sy-datum,
s_blart FOR bkpf-blart.
PARAMETERS: p_fpath TYPE string OBLIGATORY DEFAULT '/tmp/ap_extract.csv'.
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
" Get System ID and Update Timestamp
CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
IMPORTING
own_logical_system = gv_system_id
EXCEPTIONS
own_logical_system_not_defined = 1
OTHERS = 2.
CONCATENATE sy-datum sy-uzeit INTO gv_last_update.
" Internal tables for SAP data
DATA: lt_bkpf TYPE TABLE OF bkpf,
lt_rbkp TYPE TABLE OF rbkp.
" Select base documents
SELECT * FROM bkpf INTO TABLE lt_bkpf
WHERE bukrs IN s_bukrs
AND cpudt IN s_cpudt
AND blart IN s_blart
AND ( blart = 'KR' OR blart = 'KG' ). " Example FI Invoice Types
SELECT * FROM rbkp INTO TABLE lt_rbkp
WHERE bukrs IN s_bukrs
AND cpudt IN s_cpudt
AND blart IN s_blart
AND blart = 'RE'. " Example MM Invoice Type
" --- Process each invoice document ---
LOOP AT lt_bkpf ASSIGNING FIELD-SYMBOL(<fs_bkpf>).
PERFORM process_invoice USING <fs_bkpf>.
ENDLOOP.
LOOP AT lt_rbkp ASSIGNING FIELD-SYMBOL(<fs_rbkp>).
PERFORM process_mm_invoice USING <fs_rbkp>.
ENDLOOP.
" Write output to file
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*& Form PROCESS_INVOICE (Handles FI Invoices)
*&---------------------------------------------------------------------*
FORM process_invoice USING iv_bkpf TYPE bkpf.
DATA: ls_bseg TYPE bseg,
ls_lfa1 TYPE lfa1,
ld_due_date TYPE d.
DATA: ls_event TYPE ty_event_log.
" Get Vendor and other details from first line item
SELECT SINGLE * FROM bseg INTO ls_bseg
WHERE bukrs = iv_bkpf-bukrs
AND belnr = iv_bkpf-belnr
AND gjahr = iv_bkpf-gjahr
AND koart = 'K'.
IF sy-subrc = 0.
SELECT SINGLE name1 FROM lfa1 INTO ls_lfa1-name1 WHERE lifnr = ls_bseg-lifnr.
CALL FUNCTION 'DETERMINE_DUE_DATE'
EXPORTING
i_zfbdt = ls_bseg-zfbdt
i_zbd1t = ls_bseg-zbd1t
i_zbd2t = ls_bseg-zbd2t
i_zbd3t = ls_bseg-zbd3t
i_zbd1p = ls_bseg-zbd1p
i_zbd2p = ls_bseg-zbd2p
i_zterm = ls_bseg-zterm
IMPORTING
e_faedt = ld_due_date.
ENDIF.
" Helper function to populate common fields
MACRO set_common_fields.
ls_event-invoice = iv_bkpf-belnr.
ls_event-sourcesystem = gv_system_id.
ls_event-lastdataupdate = gv_last_update.
ls_event-companycode = iv_bkpf-bukrs.
ls_event-vendorname = ls_lfa1-name1.
ls_event-invoiceduedate = ld_due_date.
SELECT SINGLE wrbtr FROM bseg INTO ls_event-invoiceamount WHERE belnr = iv_bkpf-belnr AND gjahr = iv_bkpf-gjahr AND koart = 'K'.
ENDMACRO.
" 1. Invoice Received
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Received'.
CONCATENATE iv_bkpf-cpudt iv_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
" 2. Invoice Parked (if document was created as parked)
IF iv_bkpf-bstat = 'V'.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Parked'.
CONCATENATE iv_bkpf-cpudt iv_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
" 10. Invoice Posted (For non-parked, same as received. For parked, this needs CDHDR/CDPOS logic not shown for brevity)
IF iv_bkpf-bstat <> 'V'.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Posted'.
CONCATENATE iv_bkpf-budat iv_bkpf-cputm INTO ls_event-eventtime. " Using posting date
ls_event-username = iv_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
" 5. & 7. Invoice Blocked / Discrepancy Resolved from Change Docs
DATA: lt_cdhdr TYPE TABLE OF cdhdr, lt_cdpos TYPE TABLE OF cdpos.
DATA(ld_objectkey) = |{ iv_bkpf-bukrs }{ iv_bkpf-belnr }{ iv_bkpf-gjahr }|.
SELECT * FROM cdhdr INTO TABLE lt_cdhdr WHERE objectclas = 'BELEG' AND objectid = ld_objectkey.
IF sy-subrc = 0.
SELECT * FROM cdpos INTO TABLE lt_cdpos FOR ALL ENTRIES IN lt_cdhdr
WHERE changenr = lt_cdhdr-changenr AND tabname = 'BSEG' AND fname = 'ZLSPR'.
LOOP AT lt_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>).
READ TABLE lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>) WITH KEY changenr = <fs_cdpos>-changenr.
IF sy-subrc = 0.
CLEAR ls_event.
set_common_fields.
IF <fs_cdpos>-value_new IS NOT INITIAL AND <fs_cdpos>-value_old IS INITIAL.
ls_event-activityname = 'Invoice Blocked For Payment'.
ELSEIF <fs_cdpos>-value_new IS INITIAL AND <fs_cdpos>-value_old IS NOT INITIAL.
ls_event-activityname = 'Discrepancy Resolved'.
ELSE.
CONTINUE.
ENDIF.
CONCATENATE <fs_cdhdr>-udate <fs_cdhdr>-utime INTO ls_event-eventtime.
ls_event-username = <fs_cdhdr>-username.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDLOOP.
ENDIF.
" 6. 8. 9. Workflow Events (Routed, Approved, Rejected) - Simplified Example
" This requires knowledge of specific workflow templates. Placeholder logic:
" SELECT ... FROM SWW_WI2OBJ ... WHERE INSTID = [Invoice Object]
" SELECT ... FROM SWWWIHEAD ... to get status and times
" 11. & 12. & 14. Payment Proposal, Executed, Cleared
IF ls_bseg-augbl IS NOT INITIAL.
DATA: ls_regup TYPE regup.
SELECT SINGLE * FROM regup INTO ls_regup WHERE vblnr = ls_bseg-belnr.
IF sy-subrc = 0.
DATA(ld_rundate) = ls_regup-laufd.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Proposal Created'.
CONCATENATE ld_rundate '000000' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Executed'.
CONCATENATE ls_bseg-augdt '120000' INTO ls_event-eventtime. " Using clearing date as proxy
APPEND ls_event TO gt_event_log.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Payment Cleared'.
CONCATENATE ls_bseg-augdt '120001' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
" 13. Invoice Due Date Passed (Calculated)
IF ls_bseg-augdt IS NOT INITIAL AND ld_due_date IS NOT INITIAL.
IF ls_bseg-augdt > ld_due_date.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Due Date Passed'.
CONCATENATE ld_due_date '235959' INTO ls_event-eventtime.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDIF.
" 15. Invoice Cancelled
IF iv_bkpf-stblg IS NOT INITIAL.
DATA: ls_rev_bkpf TYPE bkpf.
SELECT SINGLE * FROM bkpf INTO ls_rev_bkpf WHERE belnr = iv_bkpf-stblg.
IF sy-subrc = 0.
CLEAR ls_event.
set_common_fields.
ls_event-activityname = 'Invoice Cancelled'.
CONCATENATE ls_rev_bkpf-cpudt ls_rev_bkpf-cputm INTO ls_event-eventtime.
ls_event-username = ls_rev_bkpf-usnam.
APPEND ls_event TO gt_event_log.
ENDIF.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form PROCESS_MM_INVOICE (Handles MM/Logistics Invoices)
*&---------------------------------------------------------------------*
FORM process_mm_invoice USING iv_rbkp TYPE rbkp.
" This form would be similar to PROCESS_INVOICE, but starts with RBKP.
" It needs to find the corresponding FI document in BKPF via AWKEY.
" The logic for PO/GR Matched would be included here.
" For demonstration, creating placeholder events for MM-specific activities.
DATA: ls_event TYPE ty_event_log.
ls_event-invoice = iv_rbkp-belnr.
ls_event-sourcesystem = gv_system_id.
ls_event-lastdataupdate = gv_last_update.
ls_event-companycode = iv_rbkp-bukrs.
" 1. Invoice Received (MM)
ls_event-activityname = 'Invoice Received'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" 3. Purchase Order Matched (Implicit)
ls_event-activityname = 'Purchase Order Matched'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" 4. Goods Receipt Matched (Implicit)
ls_event-activityname = 'Goods Receipt Matched'.
CONCATENATE iv_rbkp-cpudt iv_rbkp-cputm INTO ls_event-eventtime.
ls_event-username = iv_rbkp-usnam.
APPEND ls_event TO gt_event_log.
" NOTE: The rest of the events (Block, Pay, etc.) would be found by linking
" RBKP to BKPF and then reusing the logic from PROCESS_INVOICE.
" Link: BKPF-AWKEY = CONCATENATE( RBKP-BELNR, RBKP-GJAHR ).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form WRITE_OUTPUT_FILE
*&---------------------------------------------------------------------*
FORM write_output_file.
DATA: lv_string TYPE string.
OPEN DATASET p_fpath FOR OUTPUT IN TEXT MODE ENCODING UTF-8.
IF sy-subrc <> 0.
MESSAGE 'Error opening file.' TYPE 'E'.
RETURN.
ENDIF.
" Write Header
lv_string = 'Invoice,ActivityName,EventTime,SourceSystem,LastDataUpdate,UserName,CompanyCode,VendorName,InvoiceAmount,PurchaseOrderNumber,InvoiceDueDate'.
TRANSFER lv_string TO p_fpath.
" Write Data
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_event>).
" Create a comma-separated string, handling potential commas in data
CONCATENATE <fs_event>-invoice
<fs_event>-activityname
<fs_event>-eventtime
<fs_event>-sourcesystem
<fs_event>-lastdataupdate
<fs_event>-username
<fs_event>-companycode
<fs_event>-vendorname
<fs_event>-invoiceamount
<fs_event>-purchaseordernumber
<fs_event>-invoiceduedate
INTO lv_string SEPARATED BY ','.
TRANSFER lv_string TO p_fpath.
ENDLOOP.
CLOSE DATASET p_fpath.
WRITE: / 'Extraction complete. File written to:', p_fpath.
ENDFORM.
`