您的应付账款付款处理数据模板
您的应付账款付款处理数据模板
- 供应商和付款分析的核心属性
- 付款周期中的关键流程里程碑
- 适用于SAP S/4HANA系统的专用提取逻辑
应付账款付款处理属性
| 名称 | 说明 | ||
|---|---|---|---|
| 事件时间 EventTime | Activity发生的准确时间戳。 | ||
| 说明 Event Time记录Activity写入SAP数据库的具体日期和时间,为在Case内按顺序排列事件提供时间维度。该时间戳通常由系统日志或凭证抬头中的CPU日期和CPU时间字段组合而成。 在分析中,该属性对于计算周期时间、持续时间和吞吐量至关重要。它支持衡量步骤之间的时间间隔,例如从收到发票到最终批准所需的时间,这对于识别瓶颈和评估Average Invoice Approval Time等KPI表现十分关键。 为什么重要 它提供事件的时间顺序,是所有基于时间的绩效计算的基础。 获取位置 SAP表BKPF中的CPUDT(录入日期)和CPUTM(录入时间)字段,或CDHDR中的UDATE和UTIME字段 示例 2023-10-12T08:30:00.000Z2023-10-12T14:15:22.000Z2023-10-15T09:00:00.000Z | |||
| 发票编号 InvoiceNumber | 正在处理的供应商发票的唯一标识符。 | ||
| 说明 Invoice Number是SAP S/4HANA系统中跟踪应付项目生命周期的主键。它特指发票过账至总账时生成的会计凭证编号。在标准SAP术语中,它对应特定公司代码和会计年度中的凭证编号(BELNR)。 在流程分析中,该属性充当Case ID,将所有分散的活动串联起来,从最初收到并暂存发票,到经历各种审批冻结和修改,直至最终付款清账。按此标识符对事件分组,分析人员即可重建每项付款义务的完整端到端历史。 为什么重要 它是确定的Case ID,可支持端到端重建付款流程。 获取位置 SAP表BKPF(会计凭证抬头)的BELNR字段或ACDOCA的BELNR字段 示例 1900000523510000289119000006015100003002 | |||
| 活动 Activity | 为发票记录的具体任务或事件状态变更。 | ||
| 说明 该属性表示发票生命周期中发生的各个流程步骤,包括发票创建、过账、冻结、批准和付款清账等事件。Activity名称源自源系统中的事务代码、变更日志条目或工作流状态更新。 在分析中,该字段对于映射流程变体至关重要。它支持流程挖掘引擎可视化步骤顺序、识别返工循环,并确定流程偏离标准路径的位置,是事件日志的核心组成部分。 为什么重要 它定义流程图中的节点,用于可视化工作流和瓶颈。 获取位置 源自事务代码(TCODE)或变更凭证抬头(CDHDR)和项目(CDPOS) 示例 发票已过账已应用付款冻结已执行付款运行发票已清账 | |||
| 最近数据更新时间 LastDataUpdate | 表示记录最近一次提取或刷新的时间戳。 | ||
| 说明 Last Data Update标记数据成功加载到流程挖掘平台的时间点。它不代表业务事件发生的时间,而是反映数据集本身的新鲜度。这对于维护分析仪表板的可信度至关重要。 在分析中,该属性帮助用户了解当前查看信息的时效性。监控Payment Block Analysis等近实时仪表板时尤其重要,可确保决策基于SAP S/4HANA系统的最新状态。 为什么重要 它反映数据新鲜度,对于运营仪表板至关重要。 获取位置 由ETL/提取流程生成 示例 2023-10-27T23:59:59.000Z2023-11-01T06:00:00.000Z | |||
| 源系统 SourceSystem | 数据来源SAP S/4HANA实例的标识符。 | ||
| 说明 该属性用于标识提取流程数据的具体ERP安装或客户端。在多个SAP实例或旧系统并行运行的环境中,该字段可确保保留数据血缘,并支持跨系统比较。 在分析中,该字段充当高级筛选条件。它有助于分析人员在不同区域系统安装之间进行绩效基准比较,或在系统迁移项目中验证数据一致性,确保由系统配置导致的流程差异得到准确解读。 为什么重要 它可区分多系统环境中的数据来源,确保准确分段。 获取位置 SAP安装环境中的系统ID(SY-SYSID) 示例 SAP_PROD_01S4H_NA_100ERP_EU_200 | |||
| 付款冻结原因 PaymentBlockReason | 表示发票被冻结付款原因的代码。 | ||
| 说明 该属性包含阻止自动付款运行选中发票的具体原因代码。例如,“A”表示付款冻结,“R”表示发票校验,也可以是用户设置的人工冻结。 在分析中,该字段是Manual Payment Block Analysis仪表板的主要依据。通过汇总不同冻结原因的频率,企业可以诊断频繁价格差异或缺少收货记录等系统性问题,找出导致付款流程停滞的原因。 为什么重要 它识别流程停滞的具体原因,支持有针对性的根因分析。 获取位置 SAP表BSEG中的ZLSPR字段 示例 ABR* | |||
| 付款条款 PaymentTerms | 表示约定付款和折扣条件的关键代码。 | ||
| 说明 Payment Terms规定发票到期时间,以及提前付款是否适用现金折扣。该代码(例如“Z001”)对应“30天净额”或“2%/10天,30天净额”等规则。它从供应商主数据复制到发票中,但也可以人工修改。 在分析中,该属性是Early Payment Discount Optimizer和Vendor Payment Term Compliance仪表板的核心。系统可据此计算基准到期日,并识别付款是否在最佳窗口内完成,从而获得折扣节省。 为什么重要 它决定预期时间安排和财务激励,是折扣分析的关键。 获取位置 SAP表BSEG中的ZTERM字段 示例 Z001NT300001 | |||
| 供应商编号 VendorNumber | 与发票关联的供应商唯一标识符。 | ||
| 说明 Vendor Number对应SAP子分类账中的具体债权人账户,将发票与包含付款条款、银行信息和联系人信息的主数据关联起来。在S/4HANA中,它通常与Business Partner概念关联,但许多表仍保留旧字段名LIFNR。 在分析中,该属性是Vendor Payment Term Compliance仪表板的基础。分析人员可以按供应商汇总流程绩效,识别持续导致冻结、价格差异或延迟的特定供应商,并支持战略采购和供应商关系管理。 为什么重要 它支持按供应商汇总绩效,对于识别延迟的根本原因至关重要。 获取位置 SAP表BKPF中的LIFNR字段或ACDOCA中的LIFNR字段 示例 100050VEND-US-99200400 | |||
| 公司代码 CompanyCode | 用于编制资产负债表和损益表的组织单位。 | ||
| 说明 Company Code代表企业内独立的会计实体,是外部会计的核心组织单位,用于组织财务数据。每张发票只能分配给一个Company Code。 在分析中,该属性支持按法人实体或区域细分KPI。仪表板可利用它比较不同子公司的应付账款团队效率。例如,它可以帮助识别某个分支机构的人工付款冻结率是否高于企业标准。 为什么重要 它按法人实体细分流程,便于开展内部基准比较。 获取位置 SAP表BKPF中的BUKRS字段 示例 US01DE1010002000 | |||
| 净到期日 NetDueDate | 为避免罚金,发票必须完成付款的计算日期。 | ||
| 说明 净到期日是付款的最终期限,通过在基准日期上加上最大付款期限天数计算得出。该日期有时会被明确存储,但在分析视图中通常是计算字段。 在分析中,它是逾期付款和罚金跟踪器的主要基准。将实际清账日期与净到期日进行比较,可生成“逾期付款天数”指标,帮助量化应付账款团队的效率以及供应商关系受损风险。 为什么重要 它是流程的目标期限,错过期限会影响信用评级并产生额外成本。 获取位置 计算方式:基准日期+最大付款期限天数(ZBD1T/ZBD2T/ZBD3T) 示例 2023-11-302023-12-01 | |||
| 单据类型 DocumentType | 用于对会计凭证进行分类,例如供应商发票、付款和贷项通知单。 | ||
| 说明 Document Type是SAP中用于分类会计交易的双字符代码。常见类型包括供应商发票“KR”、供应商付款“KZ”和发票收货总额“RE”。它决定凭证编号范围和字段状态。 在分析中,该属性用于筛选流程范围。例如,分析人员可以排除贷项通知单,仅关注对外付款效率。它还可帮助识别正在处理的交易类型构成,并支持Process Variant Complexity仪表板。 为什么重要 它对Case进行分类,例如发票或贷项通知单,从而支持筛选分析。 获取位置 SAP表BKPF中的BLART字段 示例 KRREKZKG | |||
| 发票金额 InvoiceAmount | 以凭证货币计价的发票含税总额。 | ||
| 说明 该属性反映源凭证中记录的发票财务价值,代表需要向供应商结清的负债。在SAP S/4HANA中,通常存储于凭证货币金额字段。 在分析中,Invoice Amount用于确定工作优先级。Manual Touch Point Distribution等仪表板可利用该字段识别高投入人工活动是否被浪费在低价值发票上,帮助企业优先优化高价值交易,因为这些交易的流程失败会带来更高财务风险。 为什么重要 它体现Case的财务权重,对于确定高价值流程低效问题的优先级至关重要。 获取位置 SAP表BKPF或BSEG中的WRBTR字段 示例 1500.00250.5010000.00 | |||
| 是否无人工干预 IsTouchless | 用于标识发票是否在没有人工干预的情况下完成处理的布尔标志。 | ||
| 说明 此属性通过分析案例的事件流计算得出。如果案例仅包含自动化活动(例如用户为“system”或使用特定后台TCODE),且没有人工修改或阻塞,则标记为无人工干预。 在分析中,它是无人工干预发票率KPI的核心指标。企业可以据此跟踪自动化计划的成效,并识别哪些案例类型(例如按供应商或地区划分)能够在没有人工介入的情况下顺利完成系统处理。 为什么重要 它是衡量流程自动化程度和效率的主要指标。 获取位置 根据活动顺序和用户类型计算 示例 truefalse | |||
| 是否逾期付款 IsLatePayment | 用于标识付款是否晚于净到期日的布尔标志。 | ||
| 说明 如果清账日期严格晚于净到期日,此计算属性的值为true。它是流程绩效的二元分类标志。 在分析中,该标志用于统计逾期付款罚金频率KPI中的不合规案例数。通过直接统计“True”值,它简化了仪表板创建,无需在可视化层执行复杂的日期计算。 为什么重要 它简化了按时付款绩效KPI的计算。 获取位置 计算方式:清账日期>净到期日 示例 truefalse | |||
| 清账日期 ClearingDate | 通过付款完成发票清账的日期。 | ||
| 说明 清账日期记录应付账款分类账中的未清项目何时结清,通常由付款运行或手工过账完成。这标志着负债的结束。 在分析中,该属性用于计算流程的最终周期时间。它是“付款清账”活动使用的时间戳,并与净到期日进行比较,以确定按时付款表现。该字段直接用于付款清账效率仪表板。 为什么重要 它标志着付款流程完成,并用于判断付款是否及时。 获取位置 SAP表BSEG或AUGDT字段AUGDT 示例 2023-11-012023-11-15 | |||
| 用户名 UserName | 执行特定Activity的用户ID。 | ||
| 说明 User Name记录负责执行流程步骤的人员或系统代理的登录ID,可能是手动录入数据的用户,也可能是执行自动任务的后台作业ID,例如“BATCH_USER”。 在分析中,该属性支持计算Activity Automation Rate。通过区分人工用户和系统账户,分析人员可以衡量流程自动化水平。它还用于Manual Touch Point Distribution仪表板,以评估各团队的工作负载。 为什么重要 它区分人工工作和自动化工作,支持计算自动化率。 获取位置 SAP表BKPF中的USNAM字段或CDHDR中的USERNAME字段 示例 BSMITHWF-BATCHRJONES | |||
| 基准日期 BaselineDate | 付款条件生效并据此计算到期日的日期。 | ||
| 说明 基准日期是计算净到期日和现金折扣期限的起点。根据配置和供应商主数据,它通常是发票日期或过账日期。 在分析中,该日期是计算“是否逾期”状态的技术前提。基准日期错误往往会导致提前付款(影响现金流)或延迟付款(产生罚金)。核实该日期的准确性是供应商付款条件合规分析的一部分。 为什么重要 它是所有到期日计算的基准点。 获取位置 SAP表BSEG字段ZFBDT 示例 2023-10-012023-10-15 | |||
| 币种 Currency | 与发票金额关联的货币代码。 | ||
| 说明 Currency属性指定Invoice Amount的计价货币,例如USD、EUR或GBP。它支持正确解读财务金额,在汇总不同国际公司代码的数据时不可或缺。 在分析中,该字段确保财务KPI计算准确,通常用于将金额统一换算为报告货币,以供全球仪表板使用。在多币种环境中,如果没有该属性,Total Spend或Average Invoice Value等汇总指标将失去意义。 为什么重要 它为财务金额提供必要背景,是准确开展全球报告的基础。 获取位置 SAP表BKPF中的WAERS字段 示例 USDEURGBPJPY | |||
| 损失的折扣金额 DiscountLostAmount | 原本可获得但未实际享受的现金折扣金额。 | ||
| 说明 此计算属性表示“未能获得的资金”。系统通过检查付款是否晚于折扣期限,并在逾期时根据发票金额和未享受的折扣比例计算得出。 在分析中,这是提前付款折扣优化器的重要财务指标。它以实际货币量化流程低效的成本,为流程改进提供有力的业务依据。 为什么重要 它量化了流程延迟造成的直接财务损失。 获取位置 计算方式:如果清账日期>折扣日期,则为发票金额×折扣比例 示例 30.000.00150.00 | |||
| 现金折扣天数1 CashDiscountDays1 | 从基准日期起计算,第一档现金折扣可用的天数。 | ||
| 说明 此属性定义最优惠付款条件的有效时间窗口(例如“2%10,净额30”中的“10”)。该值来自发票行项目中存储的付款条件。 在分析中,它有助于确定提前付款折扣优化器的“目标日期”。如果发票在此窗口内完成清账,即可获得折扣。该字段有助于衡量处理周期过长带来的机会成本。 为什么重要 它定义了实现财务节省的机会窗口。 获取位置 SAP表BSEG字段ZBD1T 示例 10140 | |||
| 现金折扣百分比1 CashDiscountPercentage1 | 在第一折扣期限内付款时可获得的折扣比例。 | ||
| 说明 此属性表示供应商为鼓励提前付款而提供的财务激励比例(例如“2%10”中的“2”)。 在分析中,它用于计算“潜在现金折扣”值。将该百分比乘以发票金额,仪表板即可展示因流程低效而未能获得的资金总额,为流程自动化提供业务依据。 为什么重要 它量化潜在节省比例,是计算投资回报率的重要依据。 获取位置 SAP表BSEG字段ZBD1P 示例 2.03.00.0 | |||
| 财年 FiscalYear | 发票所属的财务年度。 | ||
| 说明 财年是用于财务报告的时间周期。它与公司代码、凭证编号共同构成SAP财务凭证的复合主键。 在分析中,它是唯一标识案例的技术必要字段,同时支持同比报告,确保“发票编号”案例ID在数十年的历史数据中保持唯一。 为什么重要 在SAP FI中唯一标识案例的技术要求。 获取位置 SAP表BKPF字段GJAHR 示例 20232024 | |||
| 采购凭证 PurchasingDocument | 与发票关联的采购订单编号。 | ||
| 说明 此属性将发票与上游采购流程关联起来,其中包含用于匹配发票的采购订单(PO)编号。并非所有发票(例如杂项费用)都有PO参考。 在分析中,此字段对于三方匹配率分析至关重要。它可以帮助分析人员区分有PO支持的发票和无PO发票,因为两者通常采用完全不同的审批工作流。此外,通过将应付账款数据与采购数据关联,它还支持端到端流程挖掘。 为什么重要 它将应付账款与采购流程关联起来,从而支持三方匹配分析和流程扩展。 获取位置 SAP表BSEG字段EBELN 示例 45000012344500009876 | |||
应付账款付款处理活动
| 活动 | 说明 | ||
|---|---|---|---|
| 付款已清账 | 标志着最终对账完成,供应商账户中的未结项目已与付款进行清账。系统从BSEG表的AUGDT(清账日期)字段中捕获此状态。 | ||
| 为什么重要 这是流程的最终状态,表示生命周期已完成且账目平衡。较高的人工清账率表明对账效率存在问题。 获取位置 BSEG表,AUGDT(清账日期)字段。 采集 AUGDT字段填充时记录 事件类型 explicit | |||
| 发票已过账 | 表示负债已正式记录在总账中。该活动源自BKPF表中的创建时间戳,或ACDOCA表中的录入日期。 | ||
| 为什么重要 这是财务时间线的主要起点,为到期日和账龄分析建立基准。 获取位置 BKPF表,使用CPUDT(录入日期)和CPUTM(录入时间)。 采集 BKPF记录创建时记录 事件类型 explicit | |||
| 已创建付款凭证 | 生成会计凭证,将银行记账并借记供应商。该记录位于BKPF表中,凭证类型为付款类型,例如ZP、KZ。 | ||
| 为什么重要 代表付款的财务实现,用于计算应付账款未付天数(DPO)。 获取位置 BKPF表,按付款专用凭证类型(BLART)筛选。 采集 BKPF付款凭证创建时记录 事件类型 explicit | |||
| 已应用付款冻结 | 表示发票行项目已设置付款冻结,因此不会被付款运行选中。系统通过变更凭证监控BSEG表中的ZLSPR字段变化来捕获此状态。 | ||
| 为什么重要 付款冻结是导致延迟付款和流程摩擦的主要原因,直接影响Manual Payment Block Analysis仪表板。 获取位置 CDPOS和CDHDR表(变更凭证),查找BSEG-ZLSPR字段的更新。 采集 CDPOS记录中的ZLSPR发生变化时记录 事件类型 explicit | |||
| 已执行付款运行 | 表示已执行付款运行并生成资金转账指令。系统通过REGUH或REGUP表中的状态更新进行跟踪。 | ||
| 为什么重要 代表付款承诺正式进入执行阶段,是分析付款批处理效率的关键。 获取位置 REGUH表,通常与运行日期和标识信息关联。 采集 付款运行状态更新时记录 事件类型 explicit | |||
| 已移除付款冻结 | 表示此前应用的付款冻结已解除,发票因此可以付款。系统会在BSEG中的ZLSPR字段从某个值变为空值或空白时识别此状态。 | ||
| 为什么重要 在没有明确工作流日志的系统中,该状态通常可作为“发票已批准”的替代指标,标志着瓶颈阶段结束。 获取位置 CDPOS和CDHDR表,查找BSEG-ZLSPR变为空白的记录。 采集 CDPOS记录移除ZLSPR时记录 事件类型 explicit | |||
| 付款条款已变更 | 记录未结发票付款条款的更新,该更新会改变到期日或折扣资格。系统通过BSEG表中ZTERM字段的变更日志进行跟踪。 | ||
| 为什么重要 频繁变更通常表明主数据错误或人工覆盖,会影响现金流预测和Vendor Payment Term Compliance。 获取位置 CDPOS和CDHDR表,查找BSEG-ZTERM字段的更新。 采集 CDPOS记录中的ZTERM发生变化时记录 事件类型 explicit | |||
| 发票到期 | 表示发票达到净到期日的计算时间戳。该时间通过将付款条款天数加到BSEG表中的基准日期得出。 | ||
| 为什么重要 作为On-Time Payment Performance和Late Payment Penalty Tracker的参考点。 获取位置 计算方式:BSEG-ZFBDT(基准日期)+BSEG-ZBD1T/ZBD2T/ZBD3T(天数)。 采集 通过比较当前日期与净到期日得出 事件类型 calculated | |||
| 发票已冲销 | 表示发票凭证已冲销或取消。系统通过检查BKPF表中的STBLG(冲销凭证)字段捕获此状态。 | ||
| 为什么重要 代表返工和流程失败,可用于识别浪费和潜在的重复工作。 获取位置 BKPF表,STBLG字段不为空。 采集 STBLG字段填充时记录 事件类型 explicit | |||
| 发票已暂存 | 表示发票已录入SAP,但尚未过账至总账,通常用于初步数据录入。系统会直接从VBKPF表捕获此状态,或识别BKPF中在转为已过账前具有暂存状态代码的凭证。 | ||
| 为什么重要 暂存标志着数据录入阶段开始,有助于衡量从收到发票到形成财务义务之间的滞后时间。 获取位置 用于存储暂存凭证抬头数据的VBKPF表,或包含特定凭证状态的BKPF表(BSTAT=V)。 采集 VBKPF条目创建时记录 事件类型 explicit | |||
| 已创建付款建议 | 表示发票已纳入付款建议运行(F110),这是自动付款程序的第一步。系统从存储结算数据的REGUH表中捕获此状态。 | ||
| 为什么重要 表示发票已在付款程序中被选中,并通过了有效性检查。 获取位置 REGUH表创建时间戳(LAUFD和LAUFI键)。 采集 REGUH记录创建时记录 事件类型 explicit | |||
| 检测到价格差异 | 表示发票价格与采购订单价格不一致的推断活动。系统通过观察过账时自动应用的特定Payment Block Key来推断,通常为用于发票校验的“R”。 | ||
| 为什么重要 用于识别人工返工的根本原因,并支持Three Way Match Rate Analysis。 获取位置 根据过账时BSEG-ZLSPR值为“R”(或系统针对价格冻结的特定配置)推断。 采集 将ZLSPR值与“R”比较 事件类型 inferred | |||
| 检测到数量差异 | 表示发票数量与收货数量不一致的推断活动。系统通过观察应用于行项目的特定Payment Block Key来推断,通常为用于数量差异的“M”。 | ||
| 为什么重要 对于分析匹配效率和供应链数据质量至关重要。 获取位置 根据BSEG-ZLSPR值为“M”(或系统针对数量冻结的特定配置)推断。 采集 将ZLSPR值与“M”比较 事件类型 inferred | |||
| 现金折扣已失效 | 标记现金折扣资格到期日期的计算事件。通过比较折扣到期日与当前日期或付款日期得出。 | ||
| 为什么重要 对于Early Payment Discount Optimizer展示已损失的财务机会至关重要。 获取位置 计算方式:BSEG-ZFBDT+BSEG-ZBD1T(折扣天数1)。 采集 通过比较日期与折扣到期日得出 事件类型 calculated | |||
提取指南
步骤
确定所需的CDS视图:确认标准SAP S/4HANA CDS视图可用。主要所需视图包括I_JournalEntry(抬头)、I_OperationalAcctgDocItem(项目,相当于BSEG)、I_SupplierInvoice(物流)、I_PaymentProposalItem(F110)和I_ChangeDocument(日志)。
配置用户权限:确保数据库用户或技术服务用户拥有与CDS实体关联的DDL SQL视图SELECT权限。通常可通过SAP HANA Studio或ABAP Eclipse Development Tools(ADT)进行管理。
准备SQL环境:打开SQL接口,例如SAP HANA Studio、连接到HANA的DBeaver,或支持SQL的流程挖掘连接器。此方法假设您可以直接访问HANA层,且CDS视图已在该层以视图形式公开。
定义范围:确定公司代码(CompanyCode)和财年范围,以限制数据量。查询运营会计凭证项目视图时,范围控制对性能至关重要。
实现活动逻辑:复制下方提供的SQL查询。该查询使用UNION ALL将14个独立逻辑块合并为单一事件日志结构。每个逻辑块对应一项特定活动,例如“发票过账”和“付款清账”。
处理更改凭证:查询包含付款条件变更和冻结操作相关部分,这些部分依赖I_ChangeDocument视图。如果您使用的S/4版本未启用该视图,可能需要将底层表CDHDR/CDPOS封装到自定义CDS视图中。
处理计算事件:检查“发票到期”和“现金折扣损失”的逻辑。这些计算事件通过在运营项目视图中的基准日期上加上天数生成。
执行提取:运行查询。对于大型数据集,强烈建议按财年或公司代码分批提取,以避免内存溢出。
核验日期格式:确保EventTime列采用YYYY-MM-DD HH:MM:SS格式。SAP HANA SQL返回的时间戳可能需要根据目标应用进行类型转换。
导出数据:将结果集保存为CSV或Parquet文件,并确保表头与最终SELECT语句中定义的列一致。
转换后上传:如果您的流程挖掘工具要求特定CSV格式(例如特定日期掩码),请在后处理脚本中,或在SQL中使用TO_VARCHAR函数完成转换。
最终验证:将样本加载到ProcessMind中,确认案例ID(发票编号)能够正确归集从过账到清账的所有活动。
配置
- 公司代码筛选:将查询限制在特定组织单元(CompanyCode = '1000'),以保持业务范围和查询性能。
- 日期范围:对过账日期或创建日期应用筛选条件(例如最近12个月),以控制数据量。
- 账户类型:筛选I_OperationalAcctgDocItem中的FinancialAccountType = 'K'(供应商),排除总账和客户行项目。
- CDS视图激活:确保I_JournalEntry、I_OperationalAcctgDocItem和I_PaymentProposalItem已激活并发布,可供SQL访问。
- 更改日志性能:查询I_ChangeDocument可能消耗较多资源。请按对象类“BELEG”和ZLSPR、ZTERM等特定字段限制子查询。
a 示例查询 sql
/* SAP S/4HANA CDS View Extraction for Accounts Payable */
/* Combined Event Log Query */
/* 1. Invoice Parked */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Invoice Parked' AS Activity,
JE.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
JE.CreatedByUser AS UserName,
NULL AS ClearingDate,
ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays)) AS NetDueDate,
CASE WHEN JE.CreationDateTime > ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays)) THEN 'True' ELSE 'False' END AS IsLatePayment,
'False' AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
WHERE JEItem.FinancialAccountType = 'K' -- Vendor
AND JE.AccountingDocumentCategory = 'V' -- Parked Document
UNION ALL
/* 2. Invoice Posted */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Invoice Posted' AS Activity,
JE.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
JEItem.PaymentBlockingReason AS PaymentBlockReason,
JE.CreatedByUser AS UserName,
NULL AS ClearingDate,
ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays)) AS NetDueDate,
'False' AS IsLatePayment,
CASE WHEN JE.CreatedByUser = 'BATCH_USER' THEN 'True' ELSE 'False' END AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND JE.AccountingDocumentCategory <> 'V' -- Exclude Parked
UNION ALL
/* 3. Price Variance Detected (Inferred at Posting) */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Price Variance Detected' AS Activity,
JE.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
JEItem.PaymentBlockingReason AS PaymentBlockReason,
'System' AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND JEItem.PaymentBlockingReason = 'R' -- Standard SAP Price Variance Block Key
UNION ALL
/* 4. Quantity Variance Detected (Inferred at Posting) */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Quantity Variance Detected' AS Activity,
JE.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
JEItem.PaymentBlockingReason AS PaymentBlockReason,
'System' AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND JEItem.PaymentBlockingReason = 'M' -- Standard SAP Quantity Variance Block Key
UNION ALL
/* 5. Payment Block Applied (via Change Document) */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Payment Block Applied' AS Activity,
CD.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
CD.NewValue AS PaymentBlockReason,
CD.CreatedByUser AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_ChangeDocument AS CD
JOIN I_JournalEntry AS JE ON CD.ObjectValue = CONCAT(JE.CompanyCode, JE.AccountingDocument)
JOIN I_OperationalAcctgDocItem AS JEItem ON JE.AccountingDocument = JEItem.AccountingDocument AND JE.CompanyCode = JEItem.CompanyCode
WHERE CD.ObjectClass = 'BELEG'
AND CD.TableName = 'BSEG'
AND CD.FieldName = 'ZLSPR'
AND CD.OldValue IS NULL AND CD.NewValue IS NOT NULL
UNION ALL
/* 6. Payment Block Removed (via Change Document) */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Payment Block Removed' AS Activity,
CD.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
CD.CreatedByUser AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_ChangeDocument AS CD
JOIN I_JournalEntry AS JE ON CD.ObjectValue = CONCAT(JE.CompanyCode, JE.AccountingDocument)
JOIN I_OperationalAcctgDocItem AS JEItem ON JE.AccountingDocument = JEItem.AccountingDocument AND JE.CompanyCode = JEItem.CompanyCode
WHERE CD.ObjectClass = 'BELEG'
AND CD.TableName = 'BSEG'
AND CD.FieldName = 'ZLSPR'
AND CD.OldValue IS NOT NULL AND (CD.NewValue IS NULL OR CD.NewValue = '')
UNION ALL
/* 7. Payment Terms Changed (via Change Document) */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Payment Terms Changed' AS Activity,
CD.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
CD.NewValue AS PaymentTerms,
NULL AS PaymentBlockReason,
CD.CreatedByUser AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_ChangeDocument AS CD
JOIN I_JournalEntry AS JE ON CD.ObjectValue = CONCAT(JE.CompanyCode, JE.AccountingDocument)
JOIN I_OperationalAcctgDocItem AS JEItem ON JE.AccountingDocument = JEItem.AccountingDocument AND JE.CompanyCode = JEItem.CompanyCode
WHERE CD.ObjectClass = 'BELEG'
AND CD.TableName = 'BSEG'
AND CD.FieldName = 'ZTERM'
UNION ALL
/* 8. Invoice Due (Calculated) */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Invoice Due' AS Activity,
TO_TIMESTAMP(ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays))) AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
'System' AS UserName,
NULL AS ClearingDate,
ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays)) AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays)) < CURRENT_DATE
UNION ALL
/* 9. Cash Discount Lost (Calculated) */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Cash Discount Lost' AS Activity,
TO_TIMESTAMP(ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.CashDiscount1Days))) AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
'System' AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND JEItem.CashDiscount1Days > 0
AND (JEItem.ClearingDate IS NULL OR JEItem.ClearingDate > ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.CashDiscount1Days)))
UNION ALL
/* 10. Payment Proposal Created */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Payment Proposal Created' AS Activity,
PPI.ProposalRunDate AS EventTime, -- Often just a date, cast to timestamp if needed
JE.CompanyCode,
PPI.Supplier AS VendorNumber,
PPI.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
PPI.CreatedByUser AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_PaymentProposalItem AS PPI
JOIN I_JournalEntry AS JE
ON PPI.CompanyCode = JE.CompanyCode
AND PPI.AccountingDocument = JE.AccountingDocument
AND PPI.FiscalYear = JE.FiscalYear
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JEItem.FinancialAccountType = 'K'
UNION ALL
/* 11. Payment Run Executed */
/* Derived from existence in payment tables with a run ID */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Payment Run Executed' AS Activity,
PPI.PaymentRunDate AS EventTime,
JE.CompanyCode,
PPI.Supplier AS VendorNumber,
PPI.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
PPI.CreatedByUser AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_PaymentProposalItem AS PPI
JOIN I_JournalEntry AS JE
ON PPI.CompanyCode = JE.CompanyCode
AND PPI.AccountingDocument = JE.AccountingDocument
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
WHERE PPI.PaymentRunID IS NOT NULL
UNION ALL
/* 12. Payment Document Created */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Payment Document Created' AS Activity,
PayJE.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
PayJE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
PayJE.CreatedByUser AS UserName,
PayJE.PostingDate AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
JOIN I_JournalEntry AS PayJE
ON JEItem.ClearingJournalEntry = PayJE.AccountingDocument
AND JEItem.ClearingJournalEntryFiscalYear = PayJE.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND JEItem.ClearingJournalEntry IS NOT NULL
UNION ALL
/* 13. Payment Cleared */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Payment Cleared' AS Activity,
TO_TIMESTAMP(JEItem.ClearingDate) AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
'System' AS UserName,
JEItem.ClearingDate,
ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays)) AS NetDueDate,
CASE WHEN JEItem.ClearingDate > ADD_DAYS(JEItem.DocumentItemDate, TO_INTEGER(JEItem.NetPaymentDays)) THEN 'True' ELSE 'False' END AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND JEItem.ClearingDate IS NOT NULL
UNION ALL
/* 14. Invoice Reversed */
SELECT
JE.OriginalReferenceDocument AS InvoiceNumber,
'Invoice Reversed' AS Activity,
RevJE.CreationDateTime AS EventTime,
JE.CompanyCode,
JEItem.Supplier AS VendorNumber,
JEItem.AmountInTransactionCurrency AS InvoiceAmount,
JE.AccountingDocumentType AS DocumentType,
JEItem.PaymentTerms,
NULL AS PaymentBlockReason,
RevJE.CreatedByUser AS UserName,
NULL AS ClearingDate,
NULL AS NetDueDate,
NULL AS IsLatePayment,
NULL AS IsTouchless,
'S4HANA' AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate
FROM I_JournalEntry AS JE
JOIN I_OperationalAcctgDocItem AS JEItem
ON JE.CompanyCode = JEItem.CompanyCode
AND JE.AccountingDocument = JEItem.AccountingDocument
AND JE.FiscalYear = JEItem.FiscalYear
JOIN I_JournalEntry AS RevJE
ON JE.ReverseDocument = RevJE.AccountingDocument
AND JE.ReverseDocumentFiscalYear = RevJE.FiscalYear
WHERE JEItem.FinancialAccountType = 'K'
AND JE.ReverseDocument IS NOT NULL 步骤
- 确认可以直接访问包含ACDOCA、BKPF、BSEG、VBKPF、REGUH、REGUP及适用变更凭证表的SAP HANA架构。将[Your SAP HANA schema]和连接详细信息替换为系统批准使用的值。
- 确认发票范围和报告期间。以YYYYMMDD格式设置[Start date]和[End date],并将[Company code filter]配置为有效的SQL谓词,例如BUKRS IN ('1000','2000')。
- 验证SAP版本以及停放凭证、付款程序状态字段、付款凭证类型和变更凭证存储的本地配置。查询使用已记录的源对象和保守的字段映射,但在投入生产前必须检查本地扩展和版本差异。
- 使用已批准的SQL客户端或提取服务对SAP HANA执行查询。查询会为每项明确提取的活动创建一行事件。结果中不存在的活动,ProcessMind不会推断。
- 检查源数据,并调整停放状态、付款凭证类型、付款建议和付款运行状态以及变更凭证对象类别对应的标记配置谓词。未经重复或无关会计凭证核对,不要放宽这些谓词。
- 使用InvoiceNumber、CompanyCode、会计年度、会计凭证编号、供应商编号及适用的行项目验证连接。确认目标系统中BKPF、BSEG、ACDOCA、REGUH和REGUP中的发票凭证编号表示方式一致。
- 核对计算所得的事件。Invoice Due在计算出的净到期日生成;当到该期限前未发生付款时,Cash Discount Lost在最早适用的折扣截止日生成。这些属于派生行,应与源记录事件明确区分。
- 将结果导出为UTF-8平面CSV或其他ProcessMind支持的表格格式。保留准确的列名InvoiceNumber、Activity、EventTime、SourceSystem和LastDataUpdate。每个事件一行,不要按发票汇总活动。
- 将事件日志上传到ProcessMind,将InvoiceNumber映射为案例标识符,将Activity映射为活动名称,将EventTime映射为事件时间戳。根据ProcessMind导入配置,将其余列映射为事件或案例属性。
配置
- 日期范围:初次提取使用连续3至6个月的时间范围。统一使用过账日期、更改日期和付款程序日期谓词,并在验证较长付款期限时扩大范围。
- 架构:将[Your SAP HANA schema]替换为拥有SAP对象的架构。确认环境是否通过所选架构公开依赖客户端的对象,或是否需要明确的客户端谓词。
- 公司筛选:配置[Company code filter],将BUKRS限制在所需公司代码范围内。对于BKPF、BSEG、ACDOCA、REGUH、REGUP及更改凭证源,在字段可用时应用相同范围。
- 凭证筛选:检查发票凭证类型谓词和付款凭证类型谓词。查询包含常见示例,但凭证类型可配置,必须与目标系统保持一致。
- 暂存发票:确认VBKPF或BKPF中的暂存凭证状态表示方式。由于不同版本和实施方案的暂存凭证状态编码可能不同,查询使用了可配置的暂存状态谓词。
- 付款变更:确认BSEG-ZLSPR和BSEG-ZTERM对应的更改凭证对象类、表名、字段名和值表示方式。必须在目标系统中核实更改凭证的存储方式和字段命名。
- 付款程序:确认REGUH和REGUP中用于建议和执行状态、运行日期、运行标识及会计凭证关联的字段。本地付款程序配置可能影响可用的状态值。
- 性能:限制日期范围和公司代码,仅选择必要列,并在连接前执行源特定筛选。对于大型数据集,可物化已筛选的源数据子集,或使用获批准的HANA计算视图或提取架构。
- 授权:所需访问权限包括相关SAP HANA架构对象,以及公开会计、付款程序和更改凭证数据的任何视图的读取权限。请与SAP安全和数据治理团队协调。
- 功能前提:相关财务会计、应付账款、付款程序和更改凭证功能必须已启用并包含数据。如果实施方案未使用某个源表,请根据系统设计配置获批准的替代数据源。
- 时间戳处理:BKPF和BSEG通常将日期和时间存储在不同字段中。查询会将两者合并为时间戳。请确认源系统时区,并在上传到ProcessMind前执行所需转换。
- 数据保护:将供应商和会计数据限制在获批准的范围内,并执行组织的数据保留、脱敏和访问策略。
a 示例查询 sql
WITH
params AS (
SELECT
TO_DATE('[Start date]', 'YYYYMMDD') AS start_date,
TO_DATE('[End date]', 'YYYYMMDD') AS end_date,
'[Source system identifier]' AS source_system
FROM DUMMY
),
base_bkpf AS (
SELECT
b.MANDT,
b.BUKRS,
b.BELNR,
b.GJAHR,
b.BLART,
b.BLDAT,
b.BUDAT,
b.CPUDT,
b.CPUTM,
b.USNAM,
b.STBLG,
b.STJAH,
b.XBLNR,
b.WAERS,
b.BKTXT,
p.source_system,
p.start_date,
p.end_date
FROM [Your SAP HANA schema].BKPF b
CROSS JOIN params p
WHERE b.BUDAT BETWEEN TO_VARCHAR(p.start_date, 'YYYYMMDD') AND TO_VARCHAR(p.end_date, 'YYYYMMDD')
AND [Company code filter]
),
invoice_bseg AS (
SELECT
k.MANDT,
k.BUKRS,
k.BELNR,
k.GJAHR,
k.BLART,
k.BLDAT,
k.BUDAT,
k.CPUDT,
k.CPUTM,
k.USNAM,
k.STBLG,
k.STJAH,
k.XBLNR,
k.WAERS,
k.BKTXT,
k.source_system,
s.BUZEI,
s.LIFNR,
s.WRBTR,
s.DMBTR,
s.ZTERM,
s.ZLSPR,
s.ZFBDT,
s.ZBD1T,
s.ZBD2T,
s.ZBD3T,
s.AUGDT,
s.AUGBL,
s.SHKZG,
s.SGTXT,
s.XREF1,
s.XREF2,
s.XREF3
FROM base_bkpf k
INNER JOIN [Your SAP HANA schema].BSEG s
ON s.MANDT = k.MANDT
AND s.BUKRS = k.BUKRS
AND s.BELNR = k.BELNR
AND s.GJAHR = k.GJAHR
WHERE s.LIFNR IS NOT NULL
AND s.LIFNR <> ''
),
acdoca_invoice AS (
SELECT
a.RCLNT AS MANDT,
a.RBUKRS AS BUKRS,
a.BELNR,
a.GJAHR,
a.BUZEI,
a.RACCT,
a.HSL,
a.WSL,
a.RWCUR,
a.BUDAT,
a.BLDAT,
a.AUGDT,
a.AUGBL
FROM [Your SAP HANA schema].ACDOCA a
WHERE a.BUDAT BETWEEN TO_VARCHAR((SELECT start_date FROM params), 'YYYYMMDD')
AND TO_VARCHAR((SELECT end_date FROM params), 'YYYYMMDD')
AND [ACDOCA company code filter]
),
invoice_cases AS (
SELECT DISTINCT
i.MANDT,
i.BUKRS,
i.BELNR,
i.GJAHR,
i.BUZEI,
i.LIFNR,
i.WRBTR,
i.ZTERM,
i.ZLSPR,
i.ZFBDT,
i.ZBD1T,
i.ZBD2T,
i.ZBD3T,
i.AUGDT,
i.AUGBL,
i.BLART,
i.BLDAT,
i.BUDAT,
i.CPUDT,
i.CPUTM,
i.USNAM,
i.STBLG,
i.STJAH,
i.XBLNR,
i.WAERS,
i.source_system,
COALESCE(NULLIF(i.XBLNR, ''), i.BELNR) AS InvoiceNumber,
ADD_DAYS(TO_DATE(COALESCE(NULLIF(i.ZFBDT, ''), i.BLDAT), 'YYYYMMDD'), COALESCE(TO_INTEGER(NULLIF(i.ZBD3T, '')), 0)) AS NetDueDate,
ADD_DAYS(TO_DATE(COALESCE(NULLIF(i.ZFBDT, ''), i.BLDAT), 'YYYYMMDD'), COALESCE(TO_INTEGER(NULLIF(i.ZBD1T, '')), 0)) AS DiscountDueDate1,
ADD_DAYS(TO_DATE(COALESCE(NULLIF(i.ZFBDT, ''), i.BLDAT), 'YYYYMMDD'), COALESCE(TO_INTEGER(NULLIF(i.ZBD2T, '')), 0)) AS DiscountDueDate2
FROM invoice_bseg i
LEFT JOIN acdoca_invoice a
ON a.MANDT = i.MANDT
AND a.BUKRS = i.BUKRS
AND a.BELNR = i.BELNR
AND a.GJAHR = i.GJAHR
AND a.BUZEI = i.BUZEI
),
change_events AS (
SELECT
c.MANDT,
c.OBJECTID,
c.TABKEY,
c.FNAME,
c.VALUE_OLD,
c.VALUE_NEW,
c.UDATE,
c.UTIME,
c.USERNAME
FROM [Your SAP HANA schema].[Your change document item table name] c
WHERE c.TABNAME = 'BSEG'
AND c.FNAME IN ('ZLSPR', 'ZTERM')
AND c.UDATE BETWEEN TO_VARCHAR((SELECT start_date FROM params), 'YYYYMMDD')
AND TO_VARCHAR((SELECT end_date FROM params), 'YYYYMMDD')
AND [Change document object class filter]
),
reguh_events AS (
SELECT
r.MANDT,
r.LAUFD,
r.LAUFI,
r.XVORL,
r.ZBUKR,
r.LIFNR,
r.VBLNR,
r.AUSFD,
r.AUSDT,
r.LAUFD AS RunDate,
r.ZALDT,
r.RZAWE,
r.XEINZ,
r.XPGRO,
r.XAVIS,
r.XVORL AS ProposalIndicator
FROM [Your SAP HANA schema].REGUH r
WHERE r.LAUFD BETWEEN TO_VARCHAR((SELECT start_date FROM params), 'YYYYMMDD')
AND TO_VARCHAR((SELECT end_date FROM params), 'YYYYMMDD')
),
regup_events AS (
SELECT
u.MANDT,
u.LAUFD,
u.LAUFI,
u.ZBUKR,
u.LIFNR,
u.VBLNR,
u.BUKRS,
u.BELNR,
u.GJAHR,
u.BUZEI,
u.XVORL,
u.AUGBL,
u.AUGDT
FROM [Your SAP HANA schema].REGUP u
WHERE u.LAUFD BETWEEN TO_VARCHAR((SELECT start_date FROM params), 'YYYYMMDD')
AND TO_VARCHAR((SELECT end_date FROM params), 'YYYYMMDD')
),
events AS (
SELECT
i.InvoiceNumber,
'Invoice Parked' AS Activity,
TO_TIMESTAMP(i.CPUDT || LPAD(COALESCE(i.CPUTM, '000000'), 6, '0'), 'YYYYMMDDHH24MISS') AS EventTime,
i.source_system AS SourceSystem,
CURRENT_TIMESTAMP AS LastDataUpdate,
i.LIFNR AS VendorNumber,
i.BUKRS AS CompanyCode,
i.WRBTR AS InvoiceAmount,
i.BLART AS DocumentType,
i.ZTERM AS PaymentTerms,
i.ZLSPR AS PaymentBlockReason,
i.USNAM AS UserName,
i.AUGDT AS ClearingDate,
i.NetDueDate,
CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END AS IsLatePayment,
FALSE AS IsTouchless
FROM invoice_cases i
INNER JOIN [Your SAP HANA schema].VBKPF v
ON v.MANDT = i.MANDT
AND v.BUKRS = i.BUKRS
AND v.BELNR = i.BELNR
AND v.GJAHR = i.GJAHR
WHERE [VBKPF parked status predicate]
UNION ALL
SELECT i.InvoiceNumber, 'Invoice Posted', TO_TIMESTAMP(i.CPUDT || LPAD(COALESCE(i.CPUTM, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i
UNION ALL
SELECT i.InvoiceNumber, 'Payment Block Applied', TO_TIMESTAMP(c.UDATE || LPAD(COALESCE(c.UTIME, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, c.VALUE_NEW, c.USERNAME, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i INNER JOIN change_events c ON c.OBJECTID = i.BELNR AND c.FNAME = 'ZLSPR' AND COALESCE(c.VALUE_OLD, '') = '' AND COALESCE(c.VALUE_NEW, '') <> ''
UNION ALL
SELECT i.InvoiceNumber, 'Price Variance Detected', TO_TIMESTAMP(i.CPUDT || LPAD(COALESCE(i.CPUTM, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i WHERE i.ZLSPR = 'R'
UNION ALL
SELECT i.InvoiceNumber, 'Quantity Variance Detected', TO_TIMESTAMP(i.CPUDT || LPAD(COALESCE(i.CPUTM, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i WHERE i.ZLSPR = 'M'
UNION ALL
SELECT i.InvoiceNumber, 'Payment Terms Changed', TO_TIMESTAMP(c.UDATE || LPAD(COALESCE(c.UTIME, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, c.VALUE_NEW, i.ZLSPR, c.USERNAME, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i INNER JOIN change_events c ON c.OBJECTID = i.BELNR AND c.FNAME = 'ZTERM'
UNION ALL
SELECT i.InvoiceNumber, 'Payment Block Removed', TO_TIMESTAMP(c.UDATE || LPAD(COALESCE(c.UTIME, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, c.VALUE_OLD, c.USERNAME, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i INNER JOIN change_events c ON c.OBJECTID = i.BELNR AND c.FNAME = 'ZLSPR' AND COALESCE(c.VALUE_OLD, '') <> '' AND COALESCE(c.VALUE_NEW, '') = ''
UNION ALL
SELECT i.InvoiceNumber, 'Invoice Due', TO_TIMESTAMP(TO_VARCHAR(i.NetDueDate, 'YYYYMMDD') || '000000', 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i WHERE i.NetDueDate IS NOT NULL
UNION ALL
SELECT i.InvoiceNumber, 'Cash Discount Lost', TO_TIMESTAMP(TO_VARCHAR(CASE WHEN i.DiscountDueDate1 <= i.DiscountDueDate2 THEN i.DiscountDueDate1 ELSE i.DiscountDueDate2 END, 'YYYYMMDD') || '000000', 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i WHERE i.AUGDT IS NULL OR i.AUGDT > CASE WHEN i.DiscountDueDate1 <= i.DiscountDueDate2 THEN i.DiscountDueDate1 ELSE i.DiscountDueDate2 END
UNION ALL
SELECT i.InvoiceNumber, 'Payment Proposal Created', TO_TIMESTAMP(r.RunDate || '000000', 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i INNER JOIN regup_events u ON u.BUKRS = i.BUKRS AND u.BELNR = i.BELNR AND u.GJAHR = i.GJAHR AND u.BUZEI = i.BUZEI INNER JOIN reguh_events r ON r.MANDT = u.MANDT AND r.LAUFD = u.LAUFD AND r.LAUFI = u.LAUFI AND r.LIFNR = u.LIFNR WHERE [Payment proposal status predicate]
UNION ALL
SELECT i.InvoiceNumber, 'Payment Run Executed', TO_TIMESTAMP(r.RunDate || '000000', 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i INNER JOIN regup_events u ON u.BUKRS = i.BUKRS AND u.BELNR = i.BELNR AND u.GJAHR = i.GJAHR AND u.BUZEI = i.BUZEI INNER JOIN reguh_events r ON r.MANDT = u.MANDT AND r.LAUFD = u.LAUFD AND r.LAUFI = u.LAUFI AND r.LIFNR = u.LIFNR WHERE [Payment run executed status predicate]
UNION ALL
SELECT i.InvoiceNumber, 'Payment Document Created', TO_TIMESTAMP(p.CPUDT || LPAD(COALESCE(p.CPUTM, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, p.BLART, i.ZTERM, i.ZLSPR, p.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i INNER JOIN [Your SAP HANA schema].BKPF p ON p.MANDT = i.MANDT AND p.BUKRS = i.BUKRS AND p.BELNR = i.AUGBL AND p.GJAHR = i.GJAHR WHERE p.BLART IN ('ZP', 'KZ')
UNION ALL
SELECT i.InvoiceNumber, 'Payment Cleared', TO_TIMESTAMP(i.AUGDT || '000000', 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i WHERE i.AUGDT IS NOT NULL
UNION ALL
SELECT i.InvoiceNumber, 'Invoice Reversed', TO_TIMESTAMP(i.CPUDT || LPAD(COALESCE(i.CPUTM, '000000'), 6, '0'), 'YYYYMMDDHH24MISS'), i.source_system, CURRENT_TIMESTAMP, i.LIFNR, i.BUKRS, i.WRBTR, i.BLART, i.ZTERM, i.ZLSPR, i.USNAM, i.AUGDT, i.NetDueDate, CASE WHEN i.AUGDT IS NOT NULL AND i.AUGDT > i.NetDueDate THEN TRUE ELSE FALSE END, FALSE
FROM invoice_cases i WHERE i.STBLG IS NOT NULL AND i.STBLG <> ''
)
SELECT
InvoiceNumber,
Activity,
EventTime,
SourceSystem,
LastDataUpdate,
VendorNumber,
CompanyCode,
InvoiceAmount,
DocumentType,
PaymentTerms,
PaymentBlockReason,
UserName,
ClearingDate,
NetDueDate,
IsLatePayment,
IsTouchless
FROM events
WHERE EventTime IS NOT NULL
ORDER BY InvoiceNumber, EventTime, Activity; 优化SAP S/4HANA中的应付账款付款处理
消除瓶颈,将您的周期时间缩短30%。
无需信用卡,5分钟完成设置。