您的订单到收款流程:销售订单处理数据模板
您的订单到收款流程:销售订单处理数据模板
- 建议收集的属性
- 需要跟踪的关键活动
- SAP ECC数据提取指南
订单到收款-销售订单处理属性
| 名称 | 说明 | ||
|---|---|---|---|
| 销售订单 SalesOrder | 销售订单凭证的唯一标识符,用作跟踪整个订单到收款流程的主要案例。 | ||
| 说明 销售订单是销售流程中的核心凭证,代表客户对货物或服务的需求。它包含从开始到结束处理客户需求所需的全部信息。 在流程挖掘中,该属性用作Case ID。每个唯一的销售订单号代表一个端到端流程实例。按销售订单分析流程,可以跟踪完整生命周期、衡量周期时间,并识别每个客户订单的流程差异。 为什么重要 这是关联所有相关活动和事件的关键,使您能够完整分析每个客户订单的端到端历程。 获取位置 位于销售凭证抬头数据表(VBAK)中,字段为VBELN。 示例 900001234590000123469000012347 | |||
| 最近数据更新时间 LastDataUpdate | 表示该记录数据最近一次从源系统刷新时间的时间戳。 | ||
| 说明 该属性记录某个事件或案例最近一次数据提取或更新的日期和时间,帮助您了解当前分析数据的新鲜度。 在仪表板和报告中,这项信息对于了解洞察的时效性至关重要。它有助于确认分析反映的是运营当前状态,还是基于较早数据,从而合理管理您对数据时效性的预期。 为什么重要 确保您了解数据的新鲜度,这对于基于流程挖掘分析及时、明智地做出决策至关重要。 获取位置 这是一个元数据属性,由数据提取工具或流程在数据导入时填充,不存储在源SAP表中。 示例 2024-06-10T05:00:00Z2024-06-11T05:00:00Z2024-06-12T05:00:00Z | |||
| 开始时间 StartTime | 表示某项活动或事件开始时间的时间戳。 | ||
| 说明 开始时间也称事件时间戳,用于记录具体活动发生的准确日期和时间。例如,记录销售订单创建、货物发出或发票过账的时间。 该时间戳是流程挖掘中所有时间分析的基础,可用于计算活动之间的周期时间、衡量案例总时长,以及识别延迟或瓶颈。准确的时间戳对于准时交付或履约周期等绩效分析仪表板至关重要。 为什么重要 这是计算周期时间和持续时长等所有绩效指标的关键属性,对于识别瓶颈至关重要。 获取位置 这是一个复合属性,通常由SAP各表中的日期字段(例如ERDAT)和时间字段(例如ERZET)组合得出,例如VBAK(销售订单)、LIKP(交付单)和VBRK(发票)。 示例 2023-04-15T09:00:12Z2023-04-16T14:30:00Z2023-04-20T11:22:45Z | |||
| 活动 Activity | 销售订单流程中发生的某个具体业务步骤或事件的名称。 | ||
| 说明 此属性描述订单到收款流程中的一个步骤,例如“销售订单已创建”“交货已创建”或“已收到付款”。这些活动是重建每个销售订单顺序流的基本组成部分。 分析这些活动的顺序和时间,是流程挖掘的核心。它有助于呈现流程图、识别瓶颈、发现流程变体,并根据标准模型检查一致性。活动通常来源于系统中记录的单据创建事件、状态变更或特定事务代码。 为什么重要 活动构成流程图的骨架,用于呈现和分析顺序流、偏差及瓶颈。 获取位置 这是一个派生属性,通常在数据提取过程中生成,将SAP事务代码(T-Codes)、凭证状态变化(例如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抬头表中找到,字段通常为“创建者”(ERNAM)或“修改者”(AENAM),例如VBAK、LIKP和VBRK。 示例 CBURKEJSMITHRWILLIAMS | |||
| 销售组织 SalesOrganization | 负责销售产品或服务的组织单位。 | ||
| 说明 销售组织是SAP中的关键组织实体,按照企业销售需求构建组织架构,负责协商销售条件并分销货物和服务。 在流程挖掘中,该属性是重要的分析维度,可用于比较不同销售单位、地区或事业部的流程绩效、效率和合规情况。这有助于发现高绩效组织的最佳实践,以及其他组织需要改进的领域。 为什么重要 支持组织基准分析,可比较不同业务单位或地区的流程效率和合规情况。 获取位置 位于销售凭证抬头数据表(VBAK)中,字段为VKORG。 示例 100025003100 | |||
| 信用检查状态 CreditCheckStatus | 表示销售凭证的信用检查状态。 | ||
| 说明 该属性显示销售订单自动或手动信用检查的结果。常见状态包括“已批准”“已拒绝”或“已冻结”。 这是“信用检查处理时间分析”仪表板的关键属性。信用检查阶段的延迟或冻结可能显著影响整体订单履约周期时间。分析该状态有助于了解信用管理流程的效率及其对销售速度的影响。 为什么重要 直接影响订单处理速度。分析该状态有助于识别信用管理中的瓶颈,了解其如何延迟订单履约。 获取位置 位于销售凭证抬头状态表(VBUK)中,或直接位于VBAK的信用状态字段中,例如CMGST。 示例 ABD | |||
| 是否准时交付 IsOnTimeDelivery | 用于表示货物是否在确认交付日期当天或之前发运的布尔标志。 | ||
| 说明 该计算属性将实际发货过账日期与销售订单的“ConfirmedDeliveryDate”进行比较。如果发货过账日期早于或等于确认日期,则标记为true,否则标记为false。 该属性简化了“准时交付绩效”仪表板的创建和准时交付率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 | |||
订单到收款-销售订单处理活动
| 活动 | 说明 | ||
|---|---|---|---|
| 创建销售订单 | 表示创建新的销售订单凭证。这是用户保存新订单时记录的明确事件,通常通过SAP中的VA01事务完成。 | ||
| 为什么重要 这是Order-to-Cash流程的主要开始事件。分析其发生时间对于衡量整体周期时间和订单接收率至关重要。 获取位置 记录在VBAK表(Sales Document Header Data)中,使用创建日期(ERDAT)和时间(ERZET)。事务代码存储在VBAK-TCODE中。 采集 基于VBAK表中的创建时间戳(ERDAT、ERZET)生成的事件。 事件类型 explicit | |||
| 发票已创建 | 表示客户发票或开票凭证已创建。这是一个明确事件,会在系统中生成新凭证,并启动流程中的付款环节。 | ||
| 为什么重要 这是“发票到付款周期时间”的起点,也是一个关键里程碑。开票延迟会直接影响现金流。 获取位置 根据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 | |||
| 货物已发出 | 这是一个关键事件,表示货物所有权已转移并正式离开仓库。这是一笔明确的财务过账,会创建物料凭证并更新库存。 | ||
| 为什么重要 这是“发运”事件,也是衡量准时交付和履约周期时间的关键里程碑。该事件会触发财务更新,并标志着实物履约流程进入不可逆阶段。 获取位置 创建包含发货过账移动类型(例如601)的物料凭证(MKPF/MSEG),并与交付单据关联。 采集 创建包含发货过账移动类型的物料凭证(MKPF/MSEG),并与交付单关联。 事件类型 explicit | |||
| 交货证明已确认 | 该活动表示客户已收到货物。系统记录交货证明时会捕获此事件,通常还会更新交付单据状态。 | ||
| 为什么重要 该事件提供实际交付日期,对于根据承诺日期准确衡量“准时交付率”至关重要。 获取位置 当交货证明状态(VBUK-PODAT)设置为“C”(已确认)时,可推断该事件。确认日期存储在VLPOD-PODAT中。该功能并非始终实施。 采集 根据交付单上的POD状态更新(VBUK-PODAT)或VLPOD表记录推断。 事件类型 inferred | |||
| 创建交货单 | 该事件标志着出库交付凭证的创建,即通知仓库开始拣货和发运活动。这是从凭证流中获取的明确事件。 | ||
| 为什么重要 这是实物履约流程的第一步。订单确认与交付创建之间的时间,反映物流流程启动的速度。 获取位置 LIKP表(SD Document: Delivery Header Data)中记录的创建。销售订单与交付的关联由凭证流表VBFA维护。 采集 基于LIKP表中的创建时间戳生成,并通过VBFA表关联。 事件类型 explicit | |||
| 发票已取消 | 表示冲销此前创建的开票凭证。这是一笔明确交易,会创建新的取消凭证以抵销原凭证。 | ||
| 为什么重要 跟踪发票取消有助于发现定价、发运差异或数据错误等问题,并支持“发票差异率”KPI分析。 获取位置 通过创建取消开票凭证(VBRK-VBTYP=“N”或“O”)捕获的明确事件。原发票在VBRK-SFAKN中引用。 采集 在VBRK中创建取消凭证,并引用原发票。 事件类型 explicit | |||
| 完成拣配 | 表示交付单中的所有物料均已从仓库完成实物拣配。如果使用Warehouse Management(WM),可根据Transfer Order的状态推断该事件。 | ||
| 为什么重要 分析拣配时间有助于优化仓库运营。此环节的延迟会直接影响整体发运时间和履约周期。 获取位置 当表LIPS中的交付项目拣配状态KOSTA变为“C”(已完全拣配)时,可推断该事件。如果启用了WM,也可根据Transfer Order确认记录(LTAK/LTAP表)推断。 采集 根据拣配状态(LIPS-KOSTA)变化或WM Transfer Order确认记录推断。 事件类型 inferred | |||
| 执行信用检查 | 表示销售订单客户的自动或人工信用检查已完成。通常可根据凭证整体信用状态的变化推断该事件。 | ||
| 为什么重要 信用检查通常是关键瓶颈。衡量该步骤所需时间,对于“Credit Check Processing Time Analysis”和加快订单处理至关重要。 获取位置 根据VBUK表(Sales Document: Header Status)中的信用状态字段推断。当VBUK-CMGST从阻止变为释放时,即标志着该活动完成。 采集 根据整体信用状态字段(VBUK-CMGST)的变更推断。 事件类型 inferred | |||
| 更改销售订单 | 表示销售订单初次创建后对现有订单进行的修改。当数量、价格或日期等字段发生变更时,系统会在专用变更日志表(CDHDR、CDPOS)中记录这些变化。 | ||
| 为什么重要 跟踪变更有助于识别返工、流程不稳定和数据质量问题。变更频率过高,可能表明初始订单录入存在问题,并导致延迟。 获取位置 从变更凭证表CDHDR(抬头)和CDPOS(项目)中提取,条件为OBJECTCLAS='VERKBELEG'。可以识别时间戳和发生变更的字段。 采集 来自销售凭证对象变更凭证表(CDHDR、CDPOS)的事件。 事件类型 explicit | |||
| 订单已取消 | 表示销售订单在履约前已取消。通常通过为订单中的所有相关项目设置“拒绝原因”来捕获。 | ||
| 为什么重要 这是一个关键失败终点,直接支持“订单取消率”KPI。了解订单何时以及为何取消,有助于发现销售流程问题。 获取位置 当销售订单所有有效项目的VBAP-ABGRU(拒绝原因)字段均已填充时推断。变更日期可在CDHDR/CDPOS中找到。 采集 根据所有项目的“拒绝原因”字段(VBAP-ABGRU)已填充推断。 事件类型 inferred | |||
| 设置交货冻结 | 表示对销售订单设置交付阻塞,阻止创建交付凭证。该事件可从变更日志中直接获取,也可根据状态表推断。 | ||
| 为什么重要 该活动与“Sales Order Blockage Rate”KPI直接相关。识别阻塞设置的原因和频率,有助于发现履约延迟的根因。 获取位置 可在VBAK-LIFSK字段对应的变更日志(CDHDR/CDPOS)中找到。也可以通过观察VBAK-LIFSK字段何时被填充来推断。 采集 来自字段VBAK-LIFSK或VBAP-LIFSP变更凭证的事件。 事件类型 explicit | |||
提取指南
步骤
- 开发程序:使用事务代码SE38或SE80创建新的可执行ABAP程序。该程序将包含完整的提取逻辑。
- 定义选择屏幕:在程序中创建数据筛选屏幕,包括销售凭证创建日期(VBAK-ERDAT)、销售组织(VBAK-VKORG)和销售凭证类型(VBAK-AUART)参数,使提取过程可复用且易于管理。
- 声明数据:定义用于存放各SAP表数据的内表和结构,例如VBAK、VBAP、VBFA、CDHDR、CDPOS、VBRK、BSAD。同时定义与所需属性匹配的事件日志最终输出结构。
- 选择基础销售订单:编写初始SELECT语句,根据用户在选择屏幕中输入的条件提取销售订单抬头(VBAK)和项目(VBAP)。这将构成待分析案例的核心数据集。
- 提取“创建”事件:遍历选定的VBAK记录,为每条记录填充事件日志结构,Activity使用“Sales Order Created”,StartTime使用VBAK-ERDAT和VBAK-ERZET。
- 提取变更日志事件:从CDHDR和CDPOS中选择OBJECTCLAS为“VERKBELEG”的记录,针对选定销售订单识别具体字段变更。例如,VBAK-LIFSK变更表示“Delivery Block Set”,VBUK-CMGST变更表示“Credit Check Performed”。其他相关变更可记录为“Sales Order Changed”。
- 提取凭证流数据:针对选定销售订单查询凭证流表VBFA。该表将销售订单与后续交货、货物移动和发票等凭证关联起来。选择所有相关凭证,以便进一步处理。
- 提取交货和履约事件:使用VBFA中的交货凭证编号查询LIKP和LIPS,提取“Delivery Created”事件。查询MKPF和MSEG,筛选移动类型“601”,记录“Goods Issued”事件。如果启用了仓库管理,则查询LTAK和LTAP,获取最后一个转储订单项目的确认时间,以确定“Picking Completed”。检查交货抬头状态VBUK-PODAT,确认“Proof of Delivery Confirmed”。
- 提取开票和付款事件:使用VBFA中的开票凭证编号查询VBRK和VBRP,提取“Invoice Created”和“Invoice Cancelled”(VBRK-FKSTO = “X”)事件。要查找“Payment Received”,将VBRK中的发票与BKPF中的会计凭证关联,再从BSAD中获取清账凭证和清账日期。
- 提取基于状态的事件:使用状态表VBUP(项目状态)和VBUK(抬头状态)推断业务事件。例如,当VBUP-GBSTA等于“C”时,项目视为“Order Item Closed”。当所有相关项目都设置了拒绝原因(VBAP-ABGRU)时,订单视为“Order Cancelled”。
- 合并并格式化:将所有捕获的事件合并到一个最终内表中。确保每条事件记录都正确填充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。
a 示例查询 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。
- 数据库兼容性:用于合并日期和时间字段的函数[Your DB-specific timestamp function]为占位符。您必须将其替换为适用于具体数据库的函数,例如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。
a 示例查询 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%,快速改善现金流。
无需信用卡,几分钟即可完成设置。