您的订单到收款流程:销售订单处理数据模板
您的订单到收款流程:销售订单处理数据模板
- 建议收集的属性
- 需要跟踪的关键活动
- SAP ECC数据提取指南
订单到收款流程:销售订单处理属性
| 名称 | 说明 | ||
|---|---|---|---|
| 销售订单 SalesOrder | 销售订单凭证的唯一标识符,是跟踪整个订单到收款流程的主要案例标识。 | ||
| 说明 销售订单是销售流程中的核心凭证,代表客户对商品或服务的需求。它包含从开始到结束处理客户需求所需的全部信息。 在流程挖掘中,此属性用作案例ID。每个唯一的销售订单编号代表一个端到端流程实例。按销售订单分析流程,可跟踪完整生命周期、衡量周期时间,并识别各个客户订单的差异。 重要性 这是关联所有相关活动和事件的关键字段,可对每笔客户订单的完整历程进行端到端分析。 获取途径 位于销售凭证抬头数据表(VBAK)的VBELN字段。 示例 900001234590000123469000012347 | |||
| 开始时间 StartTime | 表示活动或事件开始时间的时间戳。 | ||
| 说明 开始时间也称事件时间戳,记录特定活动发生的准确日期和时间。例如,销售订单创建、货物发出或发票过账的时间。 这是流程挖掘中所有时间分析的基础,可用于计算活动间的周期时间、衡量案例总时长,以及识别延迟或瓶颈。准确的时间戳对于绩效分析仪表板至关重要,例如监控按时交付或履约周期时间的仪表板。 重要性 这是计算周期时间和持续时长等各项绩效指标的关键属性,有助于识别瓶颈。 获取途径 这是一个复合属性,通常由SAP多个表中的日期字段(如ERDAT)和时间字段(如ERZET)组合而成,例如VBAK(销售订单)、LIKP(交货单)和VBRK(发票)。 示例 2023-04-15T09:00:12Z2023-04-16T14:30:00Z2023-04-20T11:22:45Z | |||
| 数据上次更新时间 LastDataUpdate | 表示此记录的数据上次从源系统刷新的时间戳。 | ||
| 说明 此属性记录特定事件或案例最近一次数据提取或更新的日期和时间,帮助您了解所分析数据的时效性。 在仪表板和报告中,这项信息有助于用户判断分析结果是否及时。它可以确认分析反映的是当前运营状态还是较早的数据,帮助用户合理预期数据的新旧程度。 重要性 让用户了解数据的时效性,这对于依据流程挖掘分析结果及时、审慎地决策至关重要。 获取途径 这是数据提取工具或流程在数据载入时填充的元数据属性,不存储在SAP源表中。 示例 2024-06-10T05:00:00Z2024-06-11T05:00:00Z2024-06-12T05:00:00Z | |||
| 活动 Activity | 销售订单流程中发生的具体业务步骤或事件的名称。 | ||
| 说明 此属性描述订单到收款流程中的单个步骤,例如“销售订单已创建”“交货单已创建”或“已收到付款”。这些活动是重建每笔销售订单流程的基础。 分析活动的顺序和时间是流程挖掘的核心。通过分析,您可以查看流程图、识别瓶颈、发现流程变体,并检查流程是否符合标准模型。活动通常根据系统记录的凭证创建事件、状态变更或特定事务代码组合推导得出。 重要性 活动构成流程图的基础,可用于查看和分析流程顺序、偏差及瓶颈。 获取途径 这是一个衍生属性,通常在数据提取过程中生成:将SAP事务代码(T-Code)、凭证状态变更(例如VBUK、VBUP表中的变更)或变更凭证日志(CDHDR、CDPOS表)映射为易于理解的活动名称。 示例 销售订单已创建交货已创建货物已发出发票已创建已收到付款 | |||
| 源系统 SourceSystem | 标识数据提取自哪个源系统。 | ||
| 说明 此属性指定数据来源系统,例如特定的SAP ECC实例名称或客户端编号。它为数据提供背景信息,尤其适用于包含多个生产系统或旧系统数据的环境。 分析时,可按数据来源筛选或细分数据。这对于比较不同系统中的流程,或在系统迁移项目中确保数据完整性和一致性尤其有用。 重要性 在多系统环境中提供必要背景信息,便于比较流程并明确数据来源。 获取途径 此值通常在数据提取过程中添加,常为代表SAP系统ID(SAPSID)或客户端(MANDT)的固定值。 示例 ECC_PROD_800SAP_ERP_EU1ECC_QAS_300 | |||
| 交货冻结 DeliveryBlock | 用于指示销售订单是否被冻结交货的代码。冻结后无法创建交货单。 | ||
| 说明 交货冻结是设置在销售订单抬头或项目级别的状态,用于在交货环节前暂时暂停流程。用户可以手动设置冻结,也可以由系统因信用额度不足或数据不完整等原因自动设置。 此属性对于“销售订单冻结与返工分析”仪表板至关重要。分析交货冻结的频率、持续时间和原因,有助于发现履约流程中的主要瓶颈。减少冻结是提高按时交付率和整体周期效率的关键。 重要性 直接揭示履约流程中的瓶颈。分析订单被冻结的原因和频率,对于提高流程效率至关重要。 获取途径 位于销售凭证抬头数据表(VBAK)的LIFSK字段。 示例 0102Z1 | |||
| 净额 NetAmount | 销售订单的总金额,不含税费和抬头级折扣。 | ||
| 说明 净额表示销售订单的货币价值,是与每个流程实例相关的重要财务指标。 此属性对于基于价值的流程挖掘至关重要,可帮助您优先改进高价值订单相关流程。分析人员可以将延迟或返工等流程问题与财务影响关联起来,为变更提供更有力的商业论证。例如,可用于分析高价值订单与低价值订单的处理效率是否存在差异。 重要性 支持基于价值的分析,帮助您优先改进对公司财务影响最大的订单流程。 获取途径 位于销售凭证抬头数据表(VBAK)的NETWR字段。 示例 1500.0012550.75850.50 | |||
| 客户编号 CustomerNumber | 下达销售订单的客户的唯一标识符。 | ||
| 说明 此属性代表“售达方”,即与销售订单关联的主要客户账户,并将交易关联到主数据中的特定客户。 按客户编号分析,可细分流程并了解客户特定的行为和绩效。例如,哪些客户的周期时间最长、返工率最高或订单变更最频繁。此分析对于改善客户关系管理和服务水平至关重要。 重要性 支持以客户为中心的分析,帮助识别影响特定客户的流程问题并衡量客户层面的绩效。 获取途径 位于销售凭证抬头数据表(VBAK)的KUNNR字段。 示例 100234100567200112 | |||
| 拒绝原因 RejectionReason | 用于说明销售订单项目被拒绝或取消原因的代码。 | ||
| 说明 拒绝原因说明销售订单或特定行项目未能履约的原因,例如客户取消、产品缺货或其他业务原因。 此属性对于“销售订单取消趋势”仪表板至关重要。通过分析常见拒绝原因,企业可以找出销售流失的根本原因,并据此改进库存管理、定价策略或客户沟通,从而降低订单取消率。 重要性 揭示订单取消的原因,支持根因分析,帮助减少销售流失并提高预测准确性。 获取途径 位于销售凭证项目数据表(VBAP)的ABGRU字段。 示例 0215Z5 | |||
| 物料编号 MaterialNumber | 所售产品或服务的唯一标识符。 | ||
| 说明 物料编号用于标识销售订单行中的具体项目。由于一张销售订单可能包含多种物料,此属性通常在项目级别进行分析。 按物料编号分析流程有助于发现特定产品相关的问题,例如某些产品是否交付周期更长、交货冻结更多或发票差异更频繁。这对于供应链和产品管理至关重要,可帮助针对不同产品线优化流程。 重要性 支持按产品分析流程,发现哪些产品与延迟、冻结或返工等流程低效问题相关。 获取途径 位于销售凭证项目数据表(VBAP)的MATNR字段。 示例 FG-1001-ARAW-205BSERV-INSTALL | |||
| 用户 User | 创建或最后修改凭证,或执行相关活动的员工用户ID。 | ||
| 说明 此属性记录流程中某个事件对应的SAP用户ID。例如,可识别创建订单的销售人员或过账货物发出的仓库员工。 按用户分析流程有助于了解工作量分布、发现培训需求,并识别不同用户执行相同任务时的差异。对于关注资源绩效、合规和人工干预的仪表板,这项属性必不可少。 重要性 帮助了解资源绩效和工作量,识别特定用户相关的流程偏差,并为合规和自动化分析提供依据。 获取途径 许多SAP抬头表中都有此字段,例如VBAK、LIKP和VBRK中的“创建者”(ERNAM)或“修改者”(AENAM)。 示例 CBURKEJSMITHRWILLIAMS | |||
| 销售组织 SalesOrganization | 负责销售产品或服务的组织单位。 | ||
| 说明 销售组织是SAP中的关键组织实体,用于根据销售需求划分公司,负责协商销售条件并分销商品和服务。 在流程挖掘中,此属性是重要的分析维度,可用于比较不同销售部门、地区或事业部的流程绩效、效率和合规情况。这有助于从绩效较好的组织中总结实践经验,并发现其他组织的改进空间。 重要性 支持组织层面的基准对比,可比较不同业务单元或地区的流程效率和合规情况。 获取途径 位于销售凭证抬头数据表(VBAK)的VKORG字段。 示例 100025003100 | |||
| 信用检查状态 CreditCheckStatus | 表示销售凭证的信用检查状态。 | ||
| 说明 此属性显示销售订单自动或手动信用检查的结果。常见状态包括“已批准”“已拒绝”或“已冻结”。 此属性是“信用检查处理时间分析”仪表板的重要依据。信用检查环节的延迟或冻结会显著影响整体订单履约周期时间。分析此状态有助于了解信用管理流程的效率及其对销售速度的影响。 重要性 直接影响订单处理速度。分析此状态有助于发现信用管理中的瓶颈,避免订单履约延迟。 获取途径 位于销售凭证抬头状态表(VBUK),或直接位于VBAK中的信用状态字段(例如CMGST)。 示例 ABD | |||
| 是否按时交付 IsOnTimeDelivery | 用于标记货物是否在确认交货日期当天或之前发运的布尔值。 | ||
| 说明 此计算属性将实际货物发出日期与销售订单的“ConfirmedDeliveryDate”进行比较。如果货物发出日期不晚于确认日期,则标记为真,否则为假。 此属性简化了“按时交付绩效”仪表板的创建和按时交付率KPI的计算。您无需在每次分析或图表中临时比较日期,即可轻松汇总和查看绩效,从而直观了解交付可靠性。 重要性 清晰简明地衡量交付绩效,便于计算整体按时交付率KPI。 获取途径 这是一个计算属性,其逻辑会将“货物发出”活动的时间戳与“ConfirmedDeliveryDate”属性的值进行比较。 示例 truefalse | |||
| 是否返工 IsRework | 用于标记销售订单在创建后是否经历了重大变更或返工活动的布尔值。 | ||
| 说明 此计算属性用于识别经历过返工的流程实例,例如出现过一次或多次“销售订单已变更”活动。项目设置期间会定义返工的具体判定逻辑,例如价格、数量或交货日期是否发生变更。 此属性对于“销售订单返工与变更频率”仪表板和销售订单返工率KPI至关重要。它便于直接筛选和比较按常规路径处理的订单与需要人工变更的订单,帮助量化返工对周期时间和成本的影响。 重要性 直接量化返工频率,便于分析返工原因及其对整体流程效率和周期时间的影响。 获取途径 这是根据事件日志计算得出的属性。其逻辑会检查是否存在“销售订单已变更”活动,或CDHDR/CDPOS表中的特定变更事件。 示例 truefalse | |||
| 确认交货日期 ConfirmedDeliveryDate | 向客户确认的商品或服务交付日期。 | ||
| 说明 这是向客户承诺的交货日期,根据物料可用情况和排程确定,可作为衡量交付绩效的基准。 此属性是“按时交付绩效”仪表板和按时交付率KPI的基础。将确认交货日期与实际“货物发出”日期进行比较,即可判断订单是按时、提前还是延迟交付。这是衡量供应链可靠性和客户满意度的主要指标。 重要性 这是衡量按时交付绩效的基准,也是影响客户满意度和供应链效率的关键KPI。 获取途径 位于销售凭证计划行表(VBEP)的EDATU字段。 示例 2023-05-102023-06-202023-07-01 | |||
| 运输条件 ShippingConditions | 定义向客户交付货物的一般运输策略。 | ||
| 说明 运输条件决定订单的运输方式,例如“标准”“加急”或“自提”。运输方式由客户协商确定,并影响物流规划。 此属性用于“运输方式效率与成本”分析。按运输条件细分流程后,企业可以分析某些运输方式是否更容易延迟或周期时间更长。这些数据有助于优化物流,并合理管理客户对交货时间的预期。 重要性 支持物流绩效分析,帮助判断特定运输方式是否与延迟或更高效率相关。 获取途径 位于销售凭证抬头数据表(VBAK)的VSBED字段。 示例 011020 | |||
订单到收款流程:销售订单处理活动
| 活动 | 说明 | ||
|---|---|---|---|
| 发票已创建 | 表示客户发票或账单凭证已创建。这是一个明确事件,会在系统中生成新凭证,并启动流程中的付款环节。 | ||
| 重要性 这是衡量“发票到付款周期时间”的起点。开票延迟会直接影响现金流。 获取途径 根据VBRK表(账单凭证:抬头数据)中的创建日期(ERDAT)记录。销售订单或交货单与发票的关联信息位于VBFA表中。 采集 根据VBRK表中的创建时间戳(ERDAT)记录的事件。 事件类型 explicit | |||
| 已收到付款 | 此事件表示已收到客户付款并将其核销到发票,从而结清未清应收账款项目。这是一个会计事件,可根据财务凭证的清账情况推断。 | ||
| 重要性 这是销售回款的最后一步,也是衡量“发票到付款周期时间”和整体“销售订单履约周期时间”的终点。 获取途径 根据BSEG表中客户行项目的清账凭证信息推断。当BSEG-AUGBL(清账凭证)和BSEG-AUGDT(清账日期)均已填写时,即表示已收到付款。 采集 根据BSEG表中应收账款行项目的清账日期(AUGDT)是否已填写推断。 事件类型 inferred | |||
| 订单已确认 | 此活动表示销售订单已通过所有初始检查,并确认进入履约阶段。通常在订单不再被阻塞且计划行中有已确认数量时推断此活动。 | ||
| 重要性 这是区分订单录入与履约的重要节点,也是衡量履约周期时间和按时交付绩效的起点。 获取途径 当VBEP中的计划行具有已确认数量(BMENG > 0),且订单未被阻止交货(例如VBUK-LIFSK为空)时,可推断此活动。 采集 根据计划行确认(VBEP-BMENG > 0)以及抬头级阻塞已解除推断。 事件类型 inferred | |||
| 订单项目已关闭 | 此活动表示销售订单项目最终关闭,即已完成交货和开票,并视为处理完毕。该状态根据项目的整体状态推断。 | ||
| 重要性 这是流程成功结束的标志。分析项目关闭时间有助于了解端到端流程时长,并发现不必要地保持开放的订单。 获取途径 根据VBUP表(销售凭证:项目状态)中的项目整体状态字段推断。当VBUP-GBSTA为“C”(已完全处理)时,项目即为关闭状态。 采集 根据项目状态(VBUP-GBSTA)变为“C”(已完全处理)推断。 事件类型 inferred | |||
| 货物已发出 | 这是一个关键事件,表示货物所有权已转移,货物正式离开仓库。此时会进行明确的财务过账,生成物料凭证并更新库存。 | ||
| 重要性 这是“发运”事件,也是衡量按时交付和履约周期时间的重要节点。该事件会触发财务更新,也是实物履约流程中不可逆的环节。 获取途径 创建物料凭证(MKPF/MSEG),移动类型为发货(例如601),并关联交货凭证。 采集 创建物料凭证(MKPF/MSEG),移动类型为发货,并关联交货凭证。 事件类型 explicit | |||
| 销售订单已创建 | 表示新销售订单凭证已创建。用户保存新订单时会记录这一明确事件,通常通过SAP中的VA01事务完成。 | ||
| 重要性 这是订单到收款流程的主要开始事件。分析其发生时间对于衡量整体周期时间和订单接收量至关重要。 获取途径 记录在VBAK表(销售凭证抬头数据)中,使用创建日期(ERDAT)和时间(ERZET)。事务代码存储在VBAK-TCODE中。 采集 根据VBAK表中的创建时间戳(ERDAT、ERZET)识别的事件。 事件类型 explicit | |||
| 交货已创建 | 此事件表示出库交货凭证已创建,仓库据此开始拣货和发运。该事件可从凭证流中直接获取。 | ||
| 重要性 这是实物履约的第一步。从订单确认到创建交货凭证的时间,反映物流流程启动的速度。 获取途径 在LIKP表(SD凭证:交货抬头数据)中创建记录。销售订单与交货凭证之间的关联保存在凭证流表VBFA中。 采集 根据LIKP表中的创建时间戳识别事件,并通过VBFA表关联销售订单。 事件类型 explicit | |||
| 发票已取消 | 表示冲销先前创建的账单凭证。这是一项明确的事务,会创建新的取消凭证以抵消原凭证。 | ||
| 重要性 跟踪发票取消情况有助于发现定价、运输差异或数据错误等问题,为“发票差异率”KPI提供依据。 获取途径 创建取消账单凭证(VBRK-VBTYP = 'N'或'O')时捕获的明确事件。原发票通过VBRK-SFAKN引用。 采集 在VBRK中创建取消凭证,并引用原发票。 事件类型 explicit | |||
| 已完成信用检查 | 表示已完成对销售订单客户的自动或人工信用检查。通常根据凭证整体信用状态的变化推断此事件。 | ||
| 重要性 信用检查往往是关键瓶颈。衡量此步骤所需的时间,对于“信用检查处理时间分析”和加快订单处理至关重要。 获取途径 根据VBUK表(销售凭证:抬头状态)中的信用状态字段推断。VBUK-CMGST从阻塞变为已释放时,即表示此活动发生。 采集 根据整体信用状态字段(VBUK-CMGST)的变更推断。 事件类型 inferred | |||
| 已确认交货证明 | 表示客户已收到货物。系统记录交货证明后会捕获此活动,通常同时更新交货单状态。 | ||
| 重要性 此事件提供实际交货日期,是根据承诺日期准确衡量“按时交付率”的关键依据。 获取途径 根据交货证明状态(VBUK-PODAT)设为“C”(已确认)推断。确认日期存储在VLPOD-PODAT中。此功能并非始终实施。 采集 根据交货单上的POD状态更新(VBUK-PODAT)或VLPOD表中的记录推断。 事件类型 inferred | |||
| 已设置交货阻塞 | 表示销售订单已设置交货阻塞,无法创建交货凭证。可从变更日志中直接获取,也可根据状态表推断。 | ||
| 重要性 此活动与“销售订单阻塞率”KPI直接相关。了解设置阻塞的原因和频率,有助于发现履约延迟的根源。 获取途径 可在字段VBAK-LIFSK的变更日志(CDHDR/CDPOS)中查找。也可通过检查VBAK-LIFSK字段何时被填入来推断。 采集 根据字段VBAK-LIFSK或VBAP-LIFSP的变更凭证记录的事件。 事件类型 explicit | |||
| 拣货已完成 | 表示交货所需的所有商品均已从仓库实际拣出。如果使用仓库管理(WM),可根据转储订单状态推断此活动。 | ||
| 重要性 分析拣货时间有助于优化仓库运营。此环节的延迟会直接影响整体发运进度和履约周期。 获取途径 当LIPS表中交货项目的拣货状态LIPS-KOSTA变为'C'(已全部拣货)时,可推断此活动。如果启用了WM,也可根据转储订单确认记录(LTAK/LTAP表)推断。 采集 根据拣货状态(LIPS-KOSTA)变更或WM转储订单确认记录推断。 事件类型 inferred | |||
| 订单已取消 | 表示销售订单在履约前已取消。通常通过为订单中的所有相关项目填写“拒绝原因”来记录。 | ||
| 重要性 这是一个关键的失败终点,可直接用于“订单取消率”KPI。了解订单取消的时间和原因,有助于发现销售流程中的问题。 获取途径 根据销售订单中所有有效项目的VBAP-ABGRU(拒绝原因)字段已填写推断。变更日期可在CDHDR/CDPOS中查找。 采集 根据所有项目的“拒绝原因”字段(VBAP-ABGRU)已填写推断。 事件类型 inferred | |||
| 销售订单已变更 | 表示销售订单创建后发生的修改。数量、价格或日期等字段变更时,系统会将其记录在专用变更日志表(CDHDR、CDPOS)中。 | ||
| 重要性 跟踪变更有助于发现返工、流程不稳定和数据质量问题。变更频繁可能表明初始订单录入存在问题,进而造成延迟。 获取途径 从变更凭证表CDHDR(抬头)和CDPOS(项目)中提取,筛选条件为OBJECTCLAS = 'VERKBELEG'。可识别时间戳和变更字段。 采集 根据销售凭证对象的变更凭证表(CDHDR、CDPOS)记录的事件。 事件类型 explicit | |||
数据提取指南
步骤
- 开发程序:使用事务代码SE38或SE80创建新的可执行ABAP程序,并在其中编写完整的数据提取逻辑。
- 定义选择屏幕:在程序中创建用于筛选数据的选择屏幕,添加销售凭证创建日期(VBAK-ERDAT)、销售组织(VBAK-VKORG)和销售凭证类型(VBAK-AUART)等参数,以便重复使用和管理提取流程。
- 声明数据:定义用于存储SAP各数据表数据的内部表和结构,例如VBAK、VBAP、VBFA、CDHDR、CDPOS、VBRK和BSAD。同时,定义符合所需属性的事件日志最终输出结构。
- 选择基础销售订单:编写初始SELECT语句,根据用户在选择屏幕中输入的条件,从VBAK提取销售订单抬头,从VBAP提取项目。这将构成待分析的核心案例数据集。
- 提取“创建”事件:遍历选中的VBAK记录。对于每条记录,将“销售订单已创建”活动写入事件日志结构,并使用VBAK-ERDAT和VBAK-ERZET作为StartTime。
- 提取更改记录事件:从CDHDR和CDPOS中选择OBJECTCLAS为“VERKBELEG”的记录,并筛选所选销售订单。遍历查询结果,识别特定字段的更改。例如,VBAK-LIFSK更改表示“已设置交货冻结”,VBUK-CMGST更改表示“已执行信用检查”。其他相关更改可记录为“销售订单已更改”。
- 提取凭证流数据:针对所选销售订单查询凭证流表VBFA。该表关联销售订单及后续凭证,例如交货、货物移动和发票。选择所有相关凭证,以便后续处理。
- 提取交货和履约事件:使用VBFA中的交货凭证编号查询LIKP和LIPS,提取“已创建交货”事件。查询MKPF和MSEG中的货物发出凭证(移动类型“601”),记录“已发货”事件。如果启用了仓库管理,则查询LTAK和LTAP,获取最后一个转储订单项目的确认时间,以确定“拣配已完成”。检查交货抬头状态VBUK-PODAT,记录“已确认交货证明”。
- 提取开票和付款事件:使用VBFA中的开票凭证编号查询VBRK和VBRP,提取“已创建发票”和“已取消发票”(VBRK-FKSTO = “X”)事件。要查找“已收到付款”事件,请将VBRK中的发票关联到BKPF中的会计凭证,再从BSAD中查找清账凭证和清账日期。
- 提取基于状态的事件:使用项目状态表VBUP和抬头状态表VBUK推断业务事件。例如,当VBUP-GBSTA等于“C”时,可将项目视为“订单项目已关闭”。如果所有相关项目都设置了“拒绝原因”(VBAP-ABGRU),则订单可视为“订单已取消”。
- 汇总并整理数据:将捕获的所有事件合并到一个最终内部表中。确保为每条事件记录正确填充SalesOrder、Activity、StartTime、User等属性,并添加SourceSystem和LastDataUpdate时间戳。
- 生成输出文件:使用GUI_DOWNLOAD函数模块或cl_gui_frontend_services=>gui_download方法,将最终内部表导出为CSV文件并保存到用户本地计算机。确保文件采用UTF-8编码。
配置
- 前提条件:需要ABAP开发人员授权(例如访问SE38事务),并对所有必需的SAP数据表具有读取权限,包括VBAK、VBAP、CDHDR、CDPOS、VBFA、LIKP、LIPS、VBRK、VBRP、MKPF、MSEG和BSAD。
- 选择参数:程序必须包含用于筛选数据的选择屏幕。关键参数包括:
- 日期范围:必须指定销售订单创建日期范围(VBAK-ERDAT)。建议从最近3至6个月开始,以控制数据集规模。
- 销售组织:按VBAK-VKORG筛选,将分析范围限定为特定业务单元。
- 销售凭证类型:按VBAK-AUART筛选,仅纳入相关订单类型(例如标准订单),排除其他类型(例如报价和退货)。
- 性能注意事项:从更改记录表(CDHDR、CDPOS)和凭证流表(VBFA)提取大量数据可能非常缓慢。应优化程序,在WHERE子句中使用索引字段。对于超大规模提取,可使用SM36事务将程序安排在非高峰时段作为后台作业运行。
- 更改记录启用情况:此方法依赖SAP的更改凭证功能。请确认关键数据元素(例如LIFSK、CMGST、ABGRU)已启用更改记录。可通过SCDO事务检查对象VERKBELEG。
查询示例 abap
REPORT Z_O2C_PM_EXTRACTOR.
*&---------------------------------------------------------------------*
*& Data Declarations
*&---------------------------------------------------------------------*
TABLES: vbak.
TYPES: BEGIN OF ty_event_log,
salesorder TYPE vbeln_va,
activity TYPE string,
starttime TYPE string,
sourcesystem TYPE logsys,
lastdataupdate TYPE string,
user TYPE ernam,
customernumber TYPE kunnr,
salesorganization TYPE vkorg,
netamount TYPE netwr,
materialnumber TYPE matnr,
deliveryblock TYPE lifsk,
rejectionreason TYPE abgru,
salesordercycletime TYPE string, " Placeholder for calculation
END OF ty_event_log.
DATA: gt_event_log TYPE TABLE OF ty_event_log.
DATA: gs_event_log TYPE ty_event_log.
DATA: gv_sysid TYPE logsys.
DATA: gv_last_update TYPE string.
*&---------------------------------------------------------------------*
*& Selection Screen
*&---------------------------------------------------------------------*
SELECT-OPTIONS: s_erdat FOR vbak-erdat OBLIGATORY,
s_vkorg FOR vbak-vkorg,
s_auart FOR vbak-auart.
PARAMETERS: p_file TYPE rlgrap-filename OBLIGATORY DEFAULT 'C:\temp\o2c_event_log.csv'.
*&---------------------------------------------------------------------*
*& Main Processing Block
*&---------------------------------------------------------------------*
START-OF-SELECTION.
CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
IMPORTING
own_logical_system = gv_sysid.
CONCATENATE sy-datum sy-uzeit INTO gv_last_update.
PERFORM get_base_data.
PERFORM write_output_file.
*&---------------------------------------------------------------------*
*& Form get_base_data
*&---------------------------------------------------------------------*
FORM get_base_data.
TYPES: BEGIN OF ty_order_item,
vbeln TYPE vbeln_va,
posnr TYPE posnr_va,
erdat TYPE erdat,
erzet TYPE erzet,
ernam TYPE ernam,
kunnr TYPE kunnr,
vkorg TYPE vkorg,
netwr TYPE netwr_ak,
matnr TYPE matnr,
lifsk TYPE lifsk,
abgru TYPE abgru,
END OF ty_order_item.
DATA: lt_order_items TYPE TABLE OF ty_order_item.
SELECT h~vbeln i~posnr h~erdat h~erzet h~ernam h~kunnr h~vkorg h~netwr i~matnr h~lifsk i~abgru
INTO TABLE lt_order_items
FROM vbak AS h
INNER JOIN vbap AS i ON h~vbeln = i~vbeln
WHERE h~erdat IN s_erdat
AND h~vkorg IN s_vkorg
AND h~auart IN s_auart.
CHECK sy-subrc = 0.
DATA(lt_vbeln_range) = VALUE rsdsselopt_t(
FOR <fs_item> IN lt_order_items WHERE ( vbeln = <fs_item>-vbeln )
( sign = 'I' option = 'EQ' low = <fs_item>-vbeln ) ).
SORT lt_vbeln_range BY low.
DELETE ADJACENT DUPLICATES FROM lt_vbeln_range COMPARING low.
PERFORM extract_order_created USING lt_order_items.
PERFORM extract_changes USING lt_vbeln_range lt_order_items.
PERFORM extract_doc_flow_events USING lt_vbeln_range lt_order_items.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_order_created
*&---------------------------------------------------------------------*
FORM extract_order_created USING it_order_items TYPE ANY TABLE.
FIELD-SYMBOLS: <fs_item> TYPE any.
DATA: lt_unique_orders TYPE HASHED TABLE OF vbeln_va WITH UNIQUE KEY table_line.
lt_unique_orders = VALUE #( FOR <order> IN it_order_items ( CONV vbeln_va( <order>-vbeln ) ) ).
LOOP AT it_order_items ASSIGNING <fs_item> WHERE table_line IN lt_unique_orders.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_item>-vbeln.
gs_event_log-activity = 'Sales Order Created'.
CONCATENATE <fs_item>-erdat <fs_item>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_item>-ernam.
gs_event_log-customernumber = <fs_item>-kunnr.
gs_event_log-salesorganization = <fs_item>-vkorg.
gs_event_log-netamount = <fs_item>-netwr.
APPEND gs_event_log TO gt_event_log.
DELETE lt_unique_orders WHERE table_line = <fs_item>-vbeln.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_changes
*&---------------------------------------------------------------------*
FORM extract_changes USING it_vbeln_range TYPE rsdsselopt_t it_order_items TYPE ANY TABLE.
DATA: lt_cdhdr TYPE TABLE OF cdhdr,
lt_cdpos TYPE TABLE OF cdpos.
SELECT * INTO TABLE lt_cdhdr FROM cdhdr
WHERE objectclas = 'VERKBELEG'
AND objectid IN it_vbeln_range
AND tcode = 'VA02'.
IF sy-subrc = 0.
SELECT * INTO TABLE lt_cdpos FROM cdpos
FOR ALL ENTRIES IN lt_cdhdr
WHERE objectclas = lt_cdhdr-objectclas
AND objectid = lt_cdhdr-objectid
AND changenr = lt_cdhdr-changenr.
ENDIF.
LOOP AT lt_cdhdr ASSIGNING FIELD-SYMBOL(<fs_cdhdr>).
DATA(lv_order_info) = REF #( it_order_items[ vbeln = <fs_cdhdr>-objectid ] ).
IF lv_order_info IS NOT BOUND. CONTINUE. ENDIF.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_cdhdr>-objectid.
gs_event_log-user = <fs_cdhdr>-username.
CONCATENATE <fs_cdhdr>-udate <fs_cdhdr>-utime INTO gs_event_log-starttime.
gs_event_log-customernumber = lv_order_info->kunnr.
gs_event_log-salesorganization = lv_order_info->vkorg.
gs_event_log-netamount = lv_order_info->netwr.
" Generic Change Event
gs_event_log-activity = 'Sales Order Changed'.
APPEND gs_event_log TO gt_event_log.
LOOP AT lt_cdpos ASSIGNING FIELD-SYMBOL(<fs_cdpos>)
WHERE objectclas = <fs_cdhdr>-objectclas
AND objectid = <fs_cdhdr>-objectid
AND changenr = <fs_cdhdr>-changenr.
CASE <fs_cdpos>-fname.
WHEN 'LIFSK'. " Delivery Block
gs_event_log-activity = 'Delivery Block Set'.
gs_event_log-deliveryblock = <fs_cdpos>-value_new.
APPEND gs_event_log TO gt_event_log.
WHEN 'CMGST'. " Credit Status
IF <fs_cdpos>-value_new = 'B'. " B = Credit Check OK
gs_event_log-activity = 'Credit Check Performed'.
APPEND gs_event_log TO gt_event_log.
ENDIF.
WHEN 'ABGRU'. " Rejection Reason
IF <fs_cdpos>-value_new IS NOT INITIAL.
gs_event_log-activity = 'Order Cancelled'.
gs_event_log-rejectionreason = <fs_cdpos>-value_new.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form extract_doc_flow_events
*&---------------------------------------------------------------------*
FORM extract_doc_flow_events USING it_vbeln_range TYPE rsdsselopt_t it_order_items TYPE ANY TABLE.
DATA: lt_vbfa TYPE TABLE OF vbfa,
lt_vbrk TYPE TABLE OF vbrk,
lt_likp TYPE TABLE OF likp,
lt_mseg TYPE TABLE OF mseg,
lt_bsad TYPE TABLE OF bsad,
lt_vbup TYPE TABLE OF vbup.
SELECT * INTO TABLE lt_vbfa FROM vbfa
WHERE vbelv IN it_vbeln_range
AND ( vbtyp_n = 'J' " Delivery
OR vbtyp_n = 'M' " Invoice
OR vbtyp_n = 'N' " Invoice Cancellation
OR vbtyp_n = 'R' ). " Goods Movement
IF lt_vbfa IS INITIAL. RETURN. ENDIF.
SELECT vbeln, erdat, erzet, ernam, fksto, belnr FROM vbrk INTO TABLE lt_vbrk
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbeln
AND ( lt_vbfa-vbtyp_n = 'M' OR lt_vbfa-vbtyp_n = 'N' ).
SELECT vbeln, erdat, erzet, ernam, podat FROM likp INTO TABLE lt_likp
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbeln AND lt_vbfa-vbtyp_n = 'J'.
SELECT mblnr, mjahr, zeile, bwart, budat, cpuzt, usnam FROM mseg INTO TABLE lt_mseg
FOR ALL ENTRIES IN lt_vbfa
WHERE mblnr = lt_vbfa-vbeln AND mjahr = lt_vbfa-mjahr AND zeile = lt_vbfa-posnn AND lt_vbfa-vbtyp_n = 'R' AND bwart = '601'.
SELECT augdt, belnr, gjahr, kunnr FROM bsad INTO TABLE lt_bsad
FOR ALL ENTRIES IN lt_vbrk
WHERE belnr = lt_vbrk-belnr AND gjahr = SUBSTRING( val = lt_vbrk-erdat len = 4 ).
SELECT vbeln, posnr, gbsta FROM vbup INTO TABLE lt_vbup
FOR ALL ENTRIES IN lt_vbfa
WHERE vbeln = lt_vbfa-vbelv AND posnr = lt_vbfa-posnv.
LOOP AT lt_vbfa ASSIGNING FIELD-SYMBOL(<fs_vbfa>).
DATA(lv_order_info) = REF #( it_order_items[ vbeln = <fs_vbfa>-vbelv ] ).
IF lv_order_info IS NOT BOUND. CONTINUE. ENDIF.
CLEAR gs_event_log.
gs_event_log-salesorder = <fs_vbfa>-vbelv.
gs_event_log-customernumber = lv_order_info->kunnr.
gs_event_log-salesorganization = lv_order_info->vkorg.
gs_event_log-netamount = lv_order_info->netwr.
gs_event_log-materialnumber = lv_order_info->matnr.
CASE <fs_vbfa>-vbtyp_n.
WHEN 'J'. " Delivery
READ TABLE lt_likp ASSIGNING FIELD-SYMBOL(<fs_likp>) WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0.
gs_event_log-activity = 'Delivery Created'.
CONCATENATE <fs_likp>-erdat <fs_likp>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_likp>-ernam.
APPEND gs_event_log TO gt_event_log.
" Picking Completed - simplified logic, check status
gs_event_log-activity = 'Picking Completed'. APPEND gs_event_log TO gt_event_log.
" POD Confirmed
IF <fs_likp>-podat IS NOT INITIAL.
gs_event_log-activity = 'Proof Of Delivery Confirmed'.
gs_event_log-starttime = <fs_likp>-podat.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
WHEN 'R'. " Goods Issue
READ TABLE lt_mseg ASSIGNING FIELD-SYMBOL(<fs_mseg>) WITH KEY mblnr = <fs_vbfa>-vbeln mjahr = <fs_vbfa>-mjahr zeile = <fs_vbfa>-posnn.
IF sy-subrc = 0.
gs_event_log-activity = 'Goods Issued'.
CONCATENATE <fs_mseg>-budat <fs_mseg>-cpuzt INTO gs_event_log-starttime.
gs_event_log-user = <fs_mseg>-usnam.
APPEND gs_event_log TO gt_event_log.
ENDIF.
WHEN 'M'. " Invoice
READ TABLE lt_vbrk ASSIGNING FIELD-SYMBOL(<fs_vbrk>) WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0.
gs_event_log-activity = 'Invoice Created'.
CONCATENATE <fs_vbrk>-erdat <fs_vbrk>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_vbrk>-ernam.
APPEND gs_event_log TO gt_event_log.
" Payment Received
READ TABLE lt_bsad ASSIGNING FIELD-SYMBOL(<fs_bsad>) WITH KEY belnr = <fs_vbrk>-belnr.
IF sy-subrc = 0 AND <fs_bsad>-augdt IS NOT INITIAL.
gs_event_log-activity = 'Payment Received'.
gs_event_log-starttime = <fs_bsad>-augdt.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDIF.
WHEN 'N'. " Invoice Cancellation
READ TABLE lt_vbrk ASSIGNING <fs_vbrk> WITH KEY vbeln = <fs_vbfa>-vbeln.
IF sy-subrc = 0 AND <fs_vbrk>-fksto = 'X'.
gs_event_log-activity = 'Invoice Cancelled'.
CONCATENATE <fs_vbrk>-erdat <fs_vbrk>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_vbrk>-ernam.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDCASE.
ENDLOOP.
" Infer other events from status
LOOP AT lt_vbup ASSIGNING FIELD-SYMBOL(<fs_vbup>).
IF <fs_vbup>-gbsta = 'C'.
DATA(lv_order_info_stat) = REF #( it_order_items[ vbeln = <fs_vbup>-vbeln ] ).
IF lv_order_info_stat IS NOT BOUND. CONTINUE. ENDIF.
gs_event_log-salesorder = <fs_vbup>-vbeln.
gs_event_log-activity = 'Order Item Closed'.
" Timestamp for closed is harder, using current time as placeholder
CONCATENATE sy-datum sy-uzeit INTO gs_event_log-starttime.
gs_event_log-user = sy-uname.
gs_event_log-customernumber = lv_order_info_stat->kunnr.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
" Order Confirmed (Simplified - assumes if not blocked it's confirmed)
LOOP AT it_order_items ASSIGNING FIELD-SYMBOL(<fs_item>).
IF <fs_item>-lifsk IS INITIAL.
gs_event_log-salesorder = <fs_item>-vbeln.
gs_event_log-activity = 'Order Confirmed'.
CONCATENATE <fs_item>-erdat <fs_item>-erzet INTO gs_event_log-starttime.
gs_event_log-user = <fs_item>-ernam.
gs_event_log-customernumber = <fs_item>-kunnr.
APPEND gs_event_log TO gt_event_log.
ENDIF.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form write_output_file
*&---------------------------------------------------------------------*
FORM write_output_file.
DATA: lt_final_output TYPE TABLE OF ty_event_log.
" Add common fields
LOOP AT gt_event_log ASSIGNING FIELD-SYMBOL(<fs_event>).
<fs_event>-sourcesystem = gv_sysid.
<fs_event>-lastdataupdate = gv_last_update.
ENDLOOP.
SORT gt_event_log BY salesorder starttime.
DELETE ADJACENT DUPLICATES FROM gt_event_log COMPARING ALL FIELDS.
lt_final_output = gt_event_log.
DATA: lt_fieldnames TYPE TABLE OF string.
APPEND 'SalesOrder' TO lt_fieldnames.
APPEND 'Activity' TO lt_fieldnames.
APPEND 'StartTime' TO lt_fieldnames.
APPEND 'SourceSystem' TO lt_fieldnames.
APPEND 'LastDataUpdate' TO lt_fieldnames.
APPEND 'User' TO lt_fieldnames.
APPEND 'CustomerNumber' TO lt_fieldnames.
APPEND 'SalesOrganization' TO lt_fieldnames.
APPEND 'NetAmount' TO lt_fieldnames.
APPEND 'MaterialNumber' TO lt_fieldnames.
APPEND 'DeliveryBlock' TO lt_fieldnames.
APPEND 'RejectionReason' TO lt_fieldnames.
APPEND 'SalesOrderCycleTime' TO lt_fieldnames.
DATA(lv_header) = REDUCE string(
INIT s = ''
FOR field IN lt_fieldnames
NEXT s = s && COND #( WHEN s = '' THEN field ELSE |,{ field }| ) ).
DATA: lt_file_content TYPE TABLE OF string.
APPEND lv_header TO lt_file_content.
LOOP AT lt_final_output INTO DATA(ls_output).
DATA(lv_line) = |"{ ls_output-salesorder }","{ ls_output-activity }","{ ls_output-starttime }","{ ls_output-sourcesystem }","{ ls_output-lastdataupdate }","{ ls_output-user }","{ ls_output-customernumber }","{ ls_output-salesorganization }",{ ls_output-netamount },"{ ls_output-materialnumber }","{ ls_output-deliveryblock }","{ ls_output-rejectionreason }","{ ls_output-salesordercycletime }"|.
APPEND lv_line TO lt_file_content.
ENDLOOP.
cl_gui_frontend_services=>gui_download(
EXPORTING
filename = p_file
filetype = 'ASC'
CHANGING
data_tab = lt_file_content ).
ENDFORM. 步骤
- 前提条件:确保您拥有SAP ECC底层数据库的直接只读访问权限。您需要使用DBeaver、SQL Server Management Studio或Oracle SQL Developer等数据库客户端连接并执行查询。
- 获取SQL脚本:复制本文档“query”部分提供的完整SQL查询。
- 连接数据库:打开数据库客户端并连接到SAP ECC数据库实例。您需要服务器地址、端口、数据库名称和相应的登录凭据。
- 配置查询:将SQL脚本粘贴到新的查询编辑器窗口。在名为SalesOrders的主公共表表达式(CTE)中找到配置部分,将开始日期(“{StartDate}”)、结束日期(“{EndDate}”)、销售组织(“{SalesOrgs}”)和凭证类型(“{DocTypes}”)占位符替换为分析所需的实际值。
- 执行查询:运行配置好的SQL脚本。根据日期范围和SAP数据库大小,查询可能需要几分钟才能完成。
- 检查结果:查询完成后,系统会显示结果集。请快速检查数据,确认其中包含预期列(SalesOrder、Activity、StartTime等),并且各类活动均有返回记录。
- 导出数据:使用数据库客户端的导出功能,将结果集保存为CSV文件。文件名可采用SAP_O2C_Event_Log.csv等易于识别的名称。
- 整理ProcessMind上传文件:在电子表格编辑器中打开CSV文件,确认列标题与所需属性完全一致(例如SalesOrder、Activity、StartTime)。确保StartTime和LastDataUpdate的日期时间格式统一且受ProcessMind支持,例如YYYY-MM-DD HH:MI:SS。
- 上传到ProcessMind:将整理好的CSV文件上传到ProcessMind项目进行分析。
配置
- 日期范围:查询使用“{StartDate}”和“{EndDate}”占位符,根据销售订单创建日期(VBAK.ERDAT)筛选数据。通常建议分析3至6个月的数据,以获得具有代表性的样本,同时避免数据库负载过高。
- 销售组织筛选:使用“{SalesOrgs}”占位符,将提取范围限定为特定销售组织(例如“1000”“2000”)。这对于聚焦分析范围和提升查询性能至关重要。
- 凭证类型筛选:使用“{DocTypes}”占位符选择特定销售订单类型(例如“OR”代表标准订单),以便将免费交货或退货等无关凭证排除在主要流程之外。
- 源系统标识符:使用硬编码占位符“{SourceSystemName}”为每条记录标记来源系统。请将其设置为有意义的SAP ECC实例名称,例如SAP_ECC_PRD。
- 数据库兼容性:用于合并日期和时间字段的函数[您的数据库专用时间戳函数]是占位符。您必须替换为适用于具体数据库的函数。例如,SAP HANA可使用TO_TIMESTAMP(CONCAT(CDHDR.UDATE, CDHDR.UZEIT), 'YYYYMMDDHH24MISS'),SQL Server可使用CAST(CDHDR.UDATE AS DATETIME) + CAST(CDHDR.UZEIT AS DATETIME)。
- 前提条件:此方法需要数据库只读凭据。数据库用户必须有权访问查询中引用的所有数据表,包括VBAK、VBAP、VBFA、CDHDR、CDPOS、LIKP、VBRK和BSAD。
查询示例 sql
WITH SalesOrders AS (
SELECT VBELN
FROM VBAK
WHERE ERDAT BETWEEN '{StartDate}' AND '{EndDate}' -- Filter by creation date
AND VKORG IN ('{SalesOrgs}') -- Filter by Sales Organization(s)
AND AUART IN ('{DocTypes}') -- Filter by Sales Document Type(s)
)
-- 1. Sales Order Created
SELECT
vbak.VBELN AS "SalesOrder",
'Sales Order Created' AS "Activity",
[Your DB-specific timestamp function](vbak.ERDAT, vbak.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbak.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBAK vbak
JOIN SalesOrders so ON vbak.VBELN = so.VBELN
UNION ALL
-- 2. Sales Order Changed
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Sales Order Changed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG' AND cdhdr.TCODE IN ('VA02')
UNION ALL
-- 3. Credit Check Performed (Release)
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Credit Check Performed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'CMGST'
AND cdpos.VALUE_NEW = 'B' -- Credit status 'Released'
UNION ALL
-- 4. Order Confirmed (Overall status not blocked)
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Order Confirmed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'GBSTK'
AND cdpos.VALUE_OLD <> 'A' AND cdpos.VALUE_NEW = 'A' -- Status changes to 'Not yet processed'
UNION ALL
-- 5. Delivery Block Set
SELECT
cdhdr.OBJECTID AS "SalesOrder",
'Delivery Block Set' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
cdpos.VALUE_NEW AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBAK'
AND cdpos.FNAME = 'LIFSK'
AND cdpos.VALUE_NEW IS NOT NULL AND cdpos.VALUE_NEW <> ''
UNION ALL
-- 6. Delivery Created
SELECT
vbfa.VBELV AS "SalesOrder",
'Delivery Created' AS "Activity",
[Your DB-specific timestamp function](likp.ERDAT, likp.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
likp.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
vbak.LIFSK AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN LIKP likp ON vbfa.VBELN = likp.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J'
UNION ALL
-- 7. Picking Completed
SELECT
vbfa.VBELV AS "SalesOrder",
'Picking Completed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN CDHDR cdhdr ON vbfa.VBELN = cdhdr.OBJECTID
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J'
AND cdhdr.OBJECTCLASS = 'LIEFERUNG'
AND cdpos.TABNAME = 'VBUK'
AND cdpos.FNAME = 'PKSTK'
AND cdpos.VALUE_NEW = 'C'
UNION ALL
-- 8. Goods Issued
SELECT
vbfa_gi.VBELV AS "SalesOrder",
'Goods Issued' AS "Activity",
[Your DB-specific timestamp function](mkpf.BUDAT, mkpf.CPUTM) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
mkpf.USNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa_gi
JOIN SalesOrders so ON vbfa_gi.VBELV = so.VBELN
JOIN MKPF mkpf ON vbfa_gi.VBELN = mkpf.XBLNR -- XBLNR is Reference Document Number
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa_gi.VBTYP_V = 'J' AND vbfa_gi.VBTYP_N = 'R'
UNION ALL
-- 9. Proof Of Delivery Confirmed
SELECT
vbfa.VBELV AS "SalesOrder",
'Proof Of Delivery Confirmed' AS "Activity",
[Your DB-specific timestamp function](likp.PODAT, '000000') AS "StartTime", -- PODAT is only a date
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
likp.AENAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN LIKP likp ON vbfa.VBELN = likp.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'J' AND likp.PODAT IS NOT NULL AND likp.PODAT <> '00000000'
UNION ALL
-- 10. Invoice Created
SELECT
vbfa.VBELV AS "SalesOrder",
'Invoice Created' AS "Activity",
[Your DB-specific timestamp function](vbrk.ERDAT, vbrk.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbrk.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'M'
UNION ALL
-- 11. Invoice Cancelled
SELECT
vbfa.VBELV AS "SalesOrder",
'Invoice Cancelled' AS "Activity",
[Your DB-specific timestamp function](vbrk.ERDAT, vbrk.ERZET) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
vbrk.ERNAM AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'M' AND vbfa.VBTYP_N = 'N'
UNION ALL
-- 12. Payment Received
SELECT
vbfa.VBELV AS "SalesOrder",
'Payment Received' AS "Activity",
[Your DB-specific timestamp function](bsad.AUGDT, '000000') AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
NULL AS "User", -- Clearing user not readily available here
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
NULL AS "MaterialNumber",
NULL AS "DeliveryBlock",
NULL AS "RejectionReason"
FROM VBFA vbfa
JOIN SalesOrders so ON vbfa.VBELV = so.VBELN
JOIN VBRK vbrk ON vbfa.VBELN = vbrk.VBELN
JOIN BSAD bsad ON vbrk.VBELN = bsad.VBLNR
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE vbfa.VBTYP_V = 'C' AND vbfa.VBTYP_N = 'M'
AND bsad.AUGDT IS NOT NULL AND bsad.AUGDT <> '00000000'
UNION ALL
-- 13. Order Item Closed
SELECT DISTINCT
cdhdr.OBJECTID AS "SalesOrder",
'Order Item Closed' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
vbap.MATNR AS "MaterialNumber",
NULL AS "DeliveryBlock",
vbap.ABGRU AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAP vbap ON cdhdr.OBJECTID = vbap.VBELN AND SUBSTRING(cdpos.TABKEY, 4, 6) = vbap.POSNR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBUP'
AND cdpos.FNAME = 'GBSTA'
AND cdpos.VALUE_NEW = 'C' -- Item is completely processed
UNION ALL
-- 14. Order Cancelled
SELECT DISTINCT
cdhdr.OBJECTID AS "SalesOrder",
'Order Cancelled' AS "Activity",
[Your DB-specific timestamp function](cdhdr.UDATE, cdhdr.UZEIT) AS "StartTime",
'{SourceSystemName}' AS "SourceSystem",
CURRENT_TIMESTAMP AS "LastDataUpdate",
cdhdr.USERNAME AS "User",
vbak.KUNNR AS "CustomerNumber",
vbak.VKORG AS "SalesOrganization",
vbak.NETWR AS "NetAmount",
vbap.MATNR AS "MaterialNumber",
NULL AS "DeliveryBlock",
cdpos.VALUE_NEW AS "RejectionReason"
FROM CDHDR cdhdr
JOIN CDPOS cdpos ON cdhdr.CHANGENR = cdpos.CHANGENR
JOIN VBAP vbap ON cdhdr.OBJECTID = vbap.VBELN AND SUBSTRING(cdpos.TABKEY, 4, 6) = vbap.POSNR
JOIN SalesOrders so ON cdhdr.OBJECTID = so.VBELN
JOIN VBAK vbak ON so.VBELN = vbak.VBELN
WHERE cdhdr.OBJECTCLASS = 'VERKBELEG'
AND cdpos.TABNAME = 'VBAP'
AND cdpos.FNAME = 'ABGRU'
AND cdpos.VALUE_NEW IS NOT NULL AND cdpos.VALUE_NEW <> ''; 立即优化订单到收款销售处理
消除瓶颈,将周期时间缩短30%,快速改善现金流。
无需信用卡,几分钟即可完成设置。