您的应付账款付款处理数据模板
您的应付账款付款处理数据模板
- 用于供应商和付款分析的核心属性
- 付款周期中的关键流程节点
- 适用于SAP S/4HANA系统的专用数据提取逻辑
应付账款付款处理属性
| 名称 | 说明 | ||
|---|---|---|---|
| 事件时间 EventTime | 活动发生的准确时间戳。 | ||
| 说明 事件时间记录活动写入SAP数据库的具体日期和时间,为按顺序排列案例中的事件提供时间维度。此时间戳通常由系统日志或凭证抬头中的CPU日期和CPU时间字段组合而成。 在分析中,此属性是计算周期时间、持续时间和吞吐量的关键依据。它可用于测量步骤之间的时间间隔,例如从收到发票到最终审批所需的时间,这对于识别瓶颈以及评估平均发票审批时间等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 | 正在处理的供应商发票的唯一标识符。 | ||
| 说明 发票编号是跟踪SAP S/4HANA系统中应付项目生命周期的主键。它特指发票过账到总账时生成的会计凭证编号。按照SAP标准术语,该编号对应特定公司代码和会计年度下的凭证编号(BELNR)。 在流程分析中,此属性用作案例ID,将各项活动关联起来,涵盖发票初始接收和暂存、各类审批冻结与修改,直至最终付款清账。按此标识符对事件分组,分析人员即可还原每笔付款义务的端到端完整历史。 重要性 它是确定的案例ID,可用于还原付款流程的端到端流转情况。 获取途径 SAP表BKPF(会计凭证抬头)的BELNR字段,或ACDOCA表的BELNR字段 示例 1900000523510000289119000006015100003002 | |||
| 活动 Activity | 记录的发票具体任务或事件状态变更。 | ||
| 说明 此属性表示发票生命周期中发生的各个流程步骤,包括创建、过账、冻结、审批和付款清账等事件。活动名称取自源系统中的事务代码、变更日志条目或工作流状态更新。 在分析中,该字段对于映射流程变体至关重要。它可帮助流程挖掘引擎呈现步骤顺序、识别返工循环,并确定流程偏离标准理想路径的位置。它是事件日志的核心组成部分。 重要性 它定义流程图中的节点,便于呈现工作流并识别瓶颈。 获取途径 取自事务代码(TCODE)或变更凭证抬头(CDHDR)和项目(CDPOS) 示例 发票过账设置付款冻结执行付款运行发票已清账 | |||
| 最近数据更新时间 LastDataUpdate | 表示记录最近一次提取或刷新的时间戳。 | ||
| 说明 最近数据更新时间标记数据成功加载到流程挖掘平台的时间。它反映的是数据集本身的新鲜度,而非业务事件发生的时间。这对于确保分析仪表板值得信赖至关重要。 在分析中,此属性可帮助用户了解当前查看的信息是否为最新数据。在监控付款冻结分析等近实时仪表板时,这一点尤为重要,可确保决策依据是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”表示发票校验冻结,也包括用户设置的手动冻结。 在分析中,此字段是手动付款冻结分析仪表板的主要依据。通过汇总不同冻结原因的出现频率,组织可以诊断导致付款流程停滞的系统性问题,例如频繁出现价格差异或缺少收货记录。 重要性 它可识别流程停滞的具体原因,支持有针对性的根因分析。 获取途径 SAP表BSEG的ZLSPR字段 示例 ABR* | |||
| 付款条件 PaymentTerms | 表示约定付款条件和折扣条件的代码。 | ||
| 说明 付款条件规定发票的到期时间,以及提前付款是否可享受现金折扣。此代码(例如“Z001”)对应“净额30天”或“2%折扣,10天内付款;净额30天”等规则。付款条件会从供应商主数据复制到发票,也可手动更改。 在分析中,此属性是提前付款折扣优化和供应商付款条件合规仪表板的核心依据。系统可据此计算基准到期日,并判断付款是否在最佳时间窗口内完成,从而获得折扣。 重要性 它决定预期付款时间和财务激励,是分析折扣的关键依据。 获取途径 SAP表BSEG的ZTERM字段 示例 Z001NT300001 | |||
| 供应商编号 VendorNumber | 与发票关联的供应商唯一标识符。 | ||
| 说明 供应商编号对应SAP子账中的特定债权人账户。它将发票关联到包含付款条件、银行信息和联系方式的主数据。在S/4HANA中,该编号通常与业务伙伴概念关联,但许多表仍沿用旧字段名LIFNR。 在分析中,此属性是供应商付款条件合规仪表板的基础。分析人员可按供应商汇总流程绩效,识别经常导致冻结、价格差异或延误的供应商。该属性也有助于制定战略采购决策和管理供应商关系。 重要性 它支持按供应商汇总绩效,对于识别延误的根本原因至关重要。 获取途径 SAP表BKPF的LIFNR字段或ACDOCA表的LIFNR字段 示例 100050VEND-US-99200400 | |||
| 公司代码 CompanyCode | 用于编制资产负债表和损益表的组织单位。 | ||
| 说明 公司代码代表企业内独立的会计实体,是外部会计的核心组织单位,用于构建财务数据。每张发票都归属于一个且仅一个公司代码。 在分析中,此属性可按法人实体或地区划分KPI。仪表板可用它比较不同子公司的应付账款团队效率。例如,它有助于识别某个分支机构的手动付款冻结率是否高于公司标准。 重要性 它按法人实体划分流程,便于开展内部对标。 获取途径 SAP表BKPF的BUKRS字段 示例 US01DE1010002000 | |||
| 净到期日 NetDueDate | 为避免罚款,发票必须支付的计算日期。 | ||
| 说明 净到期日是付款的最终截止日期,计算方式为基准日期加上最长付款期限天数。该日期有时会明确存储,但在分析视图中通常是计算得出的字段。 在分析中,它是逾期付款与罚款跟踪的主要基准。将实际清账日期与净到期日比较,可得出“逾期付款天数”指标,帮助衡量应付账款团队的效率以及供应商关系受损的风险。 重要性 它是流程的目标截止日期;未能按时完成会影响信用评级并产生费用。 获取途径 计算方式:基准日期+最长付款期限天数(ZBD1T/ZBD2T/ZBD3T) 示例 2023-11-302023-12-01 | |||
| 凭证类型 DocumentType | 用于对会计凭证分类,例如供应商发票、付款和贷项凭证。 | ||
| 说明 凭证类型是SAP中用于对会计交易分类的两位字符代码。常见类型包括:供应商发票使用“KR”,供应商付款使用“KZ”,发票收货总额使用“RE”。该类型决定凭证的编号范围和字段状态。 在分析中,此属性用于筛选流程范围。例如,分析人员可能会排除贷项凭证,只关注对外付款效率。它还有助于了解正在处理的交易类型构成,并支持流程变体复杂度仪表板。 重要性 它可对案例分类(发票或贷项凭证),便于筛选分析。 获取途径 SAP表BKPF的BLART字段 示例 KRREKZKG | |||
| 发票金额 InvoiceAmount | 发票按凭证货币计的总金额(含税)。 | ||
| 说明 此属性反映源凭证中记录的发票金额,即需要向供应商结清的负债。在SAP S/4HANA中,该金额通常存储在凭证货币金额字段中。 在分析中,发票金额可用于确定工作优先级。手动触点分布等仪表板可利用此字段,显示高投入的手动活动是否被浪费在低金额发票上。组织可据此将优化工作集中在高金额交易上,因为此类交易发生流程问题时会带来更大的财务风险。 重要性 它体现案例的财务影响,是优先处理高金额流程低效问题的重要依据。 获取途径 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 | 执行特定活动的用户ID。 | ||
| 说明 用户名记录负责执行流程步骤的人员或系统代理的登录ID。执行者可能是手动录入数据的用户,也可能是执行自动化任务的后台作业ID(例如“BATCH_USER”)。 在分析中,此属性可用于计算活动自动化率。通过区分人工用户和系统账户,分析人员可以衡量流程的自动化程度。它也用于手动触点分布仪表板,以评估各团队的工作量。 重要性 它可区分人工和自动化工作,支持计算自动化率。 获取途径 SAP表BKPF的USNAM字段或CDHDR的USERNAME字段 示例 BSMITHWF-BATCHRJONES | |||
| 会计年度 FiscalYear | 发票所属的财务年度。 | ||
| 说明 会计年度是用于财务报告的时间段。在SAP中,它与公司代码和凭证编号共同构成财务凭证的复合主键。 在分析中,它是唯一识别案例的技术必要条件,也支持同比报告。它可确保“发票编号”案例ID在数十年的数据历史中保持唯一。 重要性 在SAP FI中唯一识别案例的技术要求。 获取途径 SAP表BKPF的GJAHR字段 示例 20232024 | |||
| 基准日期 BaselineDate | 付款条件生效并据此计算到期日的起始日期。 | ||
| 说明 基准日期是计算净到期日和现金折扣期限的起点。根据系统配置和供应商主数据,它通常是发票日期或过账日期。 在分析中,此日期是计算“是否逾期”状态的技术前提。基准日期错误可能导致提前付款(影响现金流)或逾期付款(产生罚款)。核实该日期是否准确,是供应商付款条件合规分析的一部分。 重要性 它是所有到期日计算的基准。 获取途径 SAP表BSEG的ZFBDT字段 示例 2023-10-012023-10-15 | |||
| 损失的折扣金额 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 | |||
| 货币 Currency | 与发票金额关联的货币代码。 | ||
| 说明 货币属性用于指定发票金额的币种,例如USD、EUR或GBP。它有助于正确解读财务金额,也是汇总不同国际公司代码数据的必要条件。 在分析中,此字段可确保财务KPI计算准确。它通常用于将金额换算为报告货币,以便在全球仪表板中呈现。缺少此属性时,在多币种环境中,总支出或平均发票金额等汇总指标将失去意义。 重要性 它为财务金额提供必要背景,确保全球报告准确。 获取途径 SAP表BKPF的WAERS字段 示例 USDEURGBPJPY | |||
| 采购凭证 PurchasingDocument | 与发票关联的采购订单编号。 | ||
| 说明 此属性将发票关联到上游采购流程,其中包含用于匹配发票的采购订单(PO)编号。并非所有发票都有PO编号,例如杂项费用发票。 在分析中,此字段对于三方匹配率分析至关重要。分析人员可据此区分有PO和无PO的发票,因为两者通常采用截然不同的审批工作流。它还有助于将应付账款数据与采购数据关联起来,开展端到端流程挖掘。 重要性 它将应付账款与采购流程关联起来,支持三方匹配分析和流程扩展。 获取途径 SAP表BSEG的EBELN字段 示例 45000012344500009876 | |||
应付账款付款处理活动
| 活动 | 说明 | ||
|---|---|---|---|
| 付款已清账 | 标记最终对账:供应商账户中的未清项目与付款进行清账。数据取自BSEG表的AUGDT(清账日期)字段。 | ||
| 重要性 流程的最终状态,表示生命周期已结束且账目已平衡。手动清账率偏高,说明对账效率低下。 获取途径 BSEG表,字段AUGDT(清账日期)。 采集 填入AUGDT字段时记录 事件类型 explicit | |||
| 创建付款凭证 | 生成会计凭证,贷记银行账户并借记供应商账户。可在BKPF表中找到,付款凭证类型例如ZP、KZ。 | ||
| 重要性 付款的财务实现情况,用于计算应付账款周转天数(DPO)。 获取途径 BKPF表,按付款专用凭证类型(BLART)筛选。 采集 创建BKPF付款凭证时记录 事件类型 explicit | |||
| 发票过账 | 表示负债已正式记入总账。此活动根据BKPF表中的创建时间戳或ACDOCA表中的录入日期确定。 | ||
| 重要性 这是财务时间线的主要起点,可作为计算到期日和账龄分析的基准。 获取途径 使用BKPF表中的CPUDT(录入日期)和CPUTM(录入时间)。 采集 创建BKPF记录时记录 事件类型 explicit | |||
| 执行付款运行 | 表示执行付款运行并生成资金转账指令。可通过REGUH或REGUP表中的状态更新进行跟踪。 | ||
| 重要性 这是付款承诺的实际执行情况,是分析付款批处理效率的关键依据。 获取途径 REGUH表,通常与运行日期和标识相关联。 采集 付款运行状态更新时记录 事件类型 explicit | |||
| 解除付款冻结 | 表示已解除先前设置的付款冻结,发票因此可以进入付款流程。当BSEG中的ZLSPR字段从某个值变为空值时,即可识别此活动。 | ||
| 重要性 在没有明确工作流日志的系统中,通常可将其作为“发票已批准”的替代指标,标志着瓶颈阶段结束。 获取途径 CDPOS和CDHDR表,用于查找BSEG-ZLSPR变为空值的记录。 采集 CDPOS记录中的ZLSPR冻结被解除时记录 事件类型 explicit | |||
| 设置付款冻结 | 表示发票行项目已设置付款冻结,因此不会进入付款批次。可通过变更凭证监控BSEG表中ZLSPR字段的变化来捕获此活动。 | ||
| 重要性 付款冻结是造成逾期付款和流程阻碍的主要原因,会直接影响手动付款冻结分析仪表板。 获取途径 CDPOS和CDHDR表(变更凭证),用于查找BSEG-ZLSPR字段的更新。 采集 CDPOS记录中的ZLSPR发生变化时记录 事件类型 explicit | |||
| 付款条款已更改 | 记录未清发票付款条款的更新,此类更改会影响到期日或折扣资格。通过BSEG表中ZTERM字段的变更日志进行追踪。 | ||
| 重要性 频繁更改可能意味着主数据错误或手动覆盖,进而影响现金流预测和供应商付款条款一致性检查。 获取途径 CDPOS和CDHDR表,用于查找BSEG-ZTERM字段的更新。 采集 CDPOS记录中的ZTERM发生变化时记录 事件类型 explicit | |||
| 创建付款建议 | 表示发票已纳入付款建议批次(F110),这是自动付款程序的第一步。数据来自存储结算信息的REGUH表。 | ||
| 重要性 表示发票已被选中付款,并通过付款程序中的有效性检查。 获取途径 REGUH表创建时间戳(LAUFD和LAUFI键)。 采集 REGUH记录创建时记录 事件类型 explicit | |||
| 发票到期 | 表示发票达到净到期日的计算时间戳。根据BSEG表中的基准日期加上付款条款规定的天数计算得出。 | ||
| 重要性 作为按时付款绩效和逾期付款罚金跟踪器的参考点。 获取途径 计算方式:BSEG-ZFBDT(基准日期)+ BSEG-ZBD1T/ZBD2T/ZBD3T(天数)。 采集 通过将当前日期与净到期日进行比较得出 事件类型 calculated | |||
| 发票已冲销 | 表示发票凭证已冲销或取消。通过检查BKPF表中的STBLG(冲销凭证)字段获取。 | ||
| 重要性 表示返工和流程失败,可用于发现浪费和潜在的重复工作。 获取途径 BKPF表,STBLG字段非空。 采集 填入STBLG字段时记录 事件类型 explicit | |||
| 发票暂存 | 表示发票已录入SAP,但尚未过账至总账,通常用于初步数据录入。此活动可直接从VBKPF表获取,也可通过识别BKPF中状态码为暂存的凭证,在其过账前进行判断。 | ||
| 重要性 暂存标志着数据录入阶段开始,有助于衡量从收到发票到确认财务负债之间的延迟。 获取途径 暂存凭证抬头数据来自VBKPF表,或来自状态为暂存的BKPF记录(BSTAT = V)。 采集 创建VBKPF记录时记录 事件类型 explicit | |||
| 检测到价格差异 | 根据发票价格与采购订单价格不匹配推断出的活动。可通过观察过账时自动应用的特定付款冻结代码(通常为发票校验对应的“R”)来判断。 | ||
| 重要性 帮助找出人工返工的根本原因,并支持三方匹配率分析。 获取途径 根据过账时BSEG-ZLSPR的值“R”推断,或依据系统特定的价格冻结配置判断。 采集 将ZLSPR值与“R”进行比较 事件类型 inferred | |||
| 检测到数量差异 | 根据发票数量与收货数量不一致推断出的活动。可通过观察行项目上应用的特定付款冻结代码(通常为数量差异对应的“M”)来判断。 | ||
| 重要性 对于分析匹配效率和供应链数据质量至关重要。 获取途径 根据BSEG-ZLSPR的值“M”推断,或依据系统特定的数量冻结配置判断。 采集 将ZLSPR值与“M”进行比较 事件类型 inferred | |||
| 现金折扣失效 | 标记现金折扣资格到期日期的计算事件。通过比较折扣到期日与当前日期或付款日期得出。 | ||
| 重要性 对于提前付款折扣优化器而言,此指标有助于展示已错失的财务机会。 获取途径 计算方式: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开发工具(ADT)进行配置。
准备SQL环境:打开SQL接口,例如SAP HANA Studio、连接到HANA的DBeaver,或支持SQL的流程挖掘连接器。此方法假设您可直接访问HANA层中的SQL,且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等特定字段名称限制子查询。
查询示例 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]和连接信息替换为系统批准的值。
- 确认发票范围和报告期间。将[Start date]和[End date]设为YYYYMMDD格式,并将[Company code filter]配置为有效的SQL谓词,例如BUKRS IN ('1000','2000')。
- 验证SAP版本及本地配置,包括暂存凭证、付款程序状态字段、付款凭证类型和更改凭证存储。查询使用有文档说明的源对象和审慎的字段映射,但投入生产前仍须检查本地扩展和版本差异。
- 使用获批的SQL客户端或提取服务对SAP HANA执行查询。查询会为明确提取的每项活动生成一条事件记录。结果中不存在的活动,ProcessMind不会推断或补充。
- 检查源数据,并调整标记的配置谓词,以筛选暂存状态、付款凭证类型、付款建议和付款运行状态以及更改凭证对象类别。调整筛选范围前,请先核对是否存在重复或无关的会计凭证。
- 使用InvoiceNumber、CompanyCode、财年、会计凭证编号、供应商编号和行项目(如适用)验证连接。确认目标系统的BKPF、BSEG、ACDOCA、REGUH和REGUP中,发票凭证编号的表示方式一致。
- 核对计算事件。发票到期事件在计算得出的净到期日生成;如果付款未在最早适用的折扣截止日期前完成,则在该日期生成现金折扣损失事件。这些是派生记录,应与源记录事件明确区分。
- 将结果导出为扁平的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前执行所需的转换。
- 数据保护:将供应商和会计数据限制在获批范围内,并遵循组织的保留、脱敏和访问策略。
查询示例 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分钟即可完成设置。