您的应付账款付款流程数据模板
您的应付账款付款流程数据模板
- 用于财务分析的流程特定属性
- 用于付款跟踪的关键活动里程碑
- Dynamics 365 的详细提取说明
应付账款付款处理属性
| 名称 | 描述 | ||
|---|---|---|---|
| Event 时间 EventTime | 活动发生的时间戳。 | ||
| 描述 该属性记录了特定活动发生的精确日期和时间。它用于按时间顺序排列事件,并计算步骤之间的耗时。 在 Dynamics 365 中,根据所查询的表,这通常源自 为何重要 对于计算处理周期、提前期以及识别瓶颈必不可少。 获取方式 事务表中的系统字段 CreatedDateTime 或 ModifiedDateTime 示例 2023-10-01T08:30:00Z2023-10-01T14:15:22Z2023-10-05T09:00:00Z | |||
| 发票编号 InvoiceNumber | 分配给供应商发票的唯一标识符。 | ||
| 描述 发票号码是该流程视图的最终案例标识(Case ID)。它将与单张供应商发票相关的所有事件唯一分组,从而实现对其从接收到结算全过程的全面分析。 在 Microsoft Dynamics 365 中,这通常对应于 为何重要 它是将零散的应付账款活动串联为单一流程实例的核心键值。 获取方式 Table: VendInvoiceJour, Field: InvoiceId 示例 INV-2023-00198223344ACME-OCT-22 | |||
| 活动 Activity | 发生的特定任务或状态更改。 | ||
| 描述 该属性描述了流程中执行的活动或步骤,例如“发票已创建”、“发票已获批”或“付款已过账”。它将技术性的事务类型和工作流状态更改转换为易读的业务事件。 在 Dynamics 365 中,这些活动通常源自表插入(例如 为何重要 它定义了流程图的活动流向和事件顺序。 获取方式 源自各类交易表和工作流历史日志 示例 发票已创建发票已审批付款已生成 | |||
| 最后数据更新 LastDataUpdate | 数据提取或刷新时的时间戳。 | ||
| 描述 指示分析所用数据的新鲜程度。它帮助用户了解查看的是实时数据还是过往时段的快照。 这通常由 ETL(提取、转换、加载)过程生成,而非 Dynamics 365 自带的字段。 为何重要 对于建立对仪表板和 KPI 的信任至关重要。 获取方式 由提取脚本生成 示例 2023-10-25T12:00:00Z2023-11-01T06:00:00Z | |||
| 源系统 SourceSystem | 数据来源系统的名称。 | ||
| 描述 识别提取流程数据的源软件或环境。在此背景下,它将始终指向 Microsoft Dynamics 365 实例。 这在多系统并存的环境中特别有用,因为数据可能来自 ERP 和外部扫描方案的混合。 为何重要 确保多系统分析中的数据血缘和可追溯性。 获取方式 在提取期间硬编码或配置 示例 Dynamics 365 F&OD365 PRODMicrosoft Dynamics | |||
| 供应商名称 VendorName | 供应商组织名称。 | ||
| 描述 供应商的描述性名称。在 D365 中,供应商账户充当全球通讯簿( 提供易于理解的名称有助于生成“供应商关系复杂度视图”,并使仪表板便于业务用户使用。 为何重要 为供应商账号提供背景信息。 获取方式 Table: DirPartyTable (via VendTable), Field: Name 示例 Contoso Office SupplyFabrikam ElectronicsLitware Inc. | |||
| 供应商账户 VendorAccount | 供应商的唯一账号。 | ||
| 描述 参与交易的供应商唯一标识。在 Dynamics 365 中,这对应于 该属性是“供应商关系复杂度视图”的核心,支持对每个特定供应商关系的绩效和摩擦进行分析。 为何重要 支持按供应商细分流程性能。 获取方式 Table: VendInvoiceJour, Field: InvoiceAccount or OrderAccount 示例 US-101V000452001 | |||
| 公司代码 CompanyCode | 法律实体或子公司标识。 | ||
| 描述 代表组织内处理发票的法律实体。在 Microsoft Dynamics 365 中,这通过系统字段 该属性对于“端到端前置时间分析”至关重要,支持在不同子公司或地理区域之间进行对比。 为何重要 支持对不同业务单元或国家/地区进行对比分析。 获取方式 Table: VendInvoiceJour, Field: DataAreaId 示例 USMFDEMFGBSI | |||
| 到期日期 DueDate | 发票应支付的截止日期。 | ||
| 描述 必须结清付款以避免罚金的合同日期。在 Dynamics 365 中,该日期存储在发票抬头或事务记录的 它是“按时付款率”KPI 的核心基准,有助于在“应付账款流程吞吐量与规模”视图中优先处理工作。 为何重要 衡量按时付款绩效的基准。 获取方式 Table: VendInvoiceJour or VendTrans, Field: DueDate 示例 2023-11-302023-12-15 | |||
| 发票日期 InvoiceDate | 发票上注明的凭证日期。 | ||
| 描述 印在供应商发票上的日期。在 Dynamics 365 中,即为 用于“端到端前置时间分析”,以从供应商角度衡量整个生命周期。 为何重要 定义发票账龄期的起点。 获取方式 Table: VendInvoiceJour, Field: InvoiceDate 示例 2023-10-012023-10-15 | |||
| 发票金额 InvoiceAmount | 发票的总货币价值。 | ||
| 描述 以交易币种计的发票总额。在 Dynamics 365 中,这通常位于发票日记账表中的 用于“重复付款风险检测”仪表板,将金额与供应商详情进行关联分析。 为何重要 对于分析支出规模和财务风险至关重要。 获取方式 Table: VendInvoiceJour, Field: InvoiceAmount 示例 1500.00245.5010000.00 | |||
| 用户ID UserId | 执行该活动的用户标识。 | ||
| 描述 识别负责特定活动(如批准发票或过账付款)的系统用户。源自 D365 的 用于“付款冻结与摩擦分析”,以查看特定经办人是否比其他人更容易触发冻结。 为何重要 支持对人员行为和职责分离情况进行分析。 获取方式 事务/历史表中的系统字段 CreatedBy/ModifiedBy 示例 jdoeadminworkflow_sys | |||
| 部门 Department | 负责该成本的部门。 | ||
| 描述 代表内部部门的财务维度。在 Dynamics 365 中,维度是动态存储的(通常在 该属性用于“供应商关系复杂度视图”,以观察哪些内部部门产生的应付账款量最大。 为何重要 支持组织层级的钻取和责任分析。 获取方式 Table: VendInvoiceJour, Field: DefaultDimension (Requires DimensionAttributeLevelValue view) 示例 IT财务运营 | |||
| 采购订单号 PurchaseOrderNumber | 关联采购订单的参考编号。 | ||
| 描述 将发票链接至原始采购单据。在 Dynamics 365 中,对应 此属性通过区分“有 PO 发票”和“无 PO 发票”,为“采购订单匹配与差异趋势”仪表板提供支持。 为何重要 对于分析“从采购到付款”的匹配率至关重要。 获取方式 Table: VendInvoiceJour, Field: PurchId 示例 PO-000455000342PO-22-998 | |||
| 付款方式 PaymentMethod | 支付发票所用的方式(如:支票、电汇、电子资金转账)。 | ||
| 描述 定义资金转入供应商的方式。在 Dynamics 365 中,对应 此属性用于“付款执行周期”仪表板,以评估不同付款批次类型的效率。 为何重要 用于解释付款执行阶段的偏差。 获取方式 Table: VendInvoiceJour (joined to PaymMode info) or VendTrans 示例 支票ACHWIRE | |||
| 付款条款 PaymentTerms | 代表已达成一致的付款条件的代码。 | ||
| 描述 规定截止日期和折扣的配置代码(如 Net30)。在 Dynamics 365 中,即为 将其与“周期时间”结合分析,可观察流程延迟是否违反了约定的条款。 为何重要 为截止日期计算提供背景信息。 获取方式 Table: VendInvoiceJour, Field: PaymTermId 示例 Net302%10Net30货到付款 | |||
| 凭证号码 VoucherNumber | 与该事务关联的总账凭证编号。 | ||
| 描述 会计分录的内部总账标识。在 Dynamics 365 中, 虽然这偏向技术性,但对于“流程路径与合规审计”非常有用,可以追溯到总账(GL)进行对账。 为何重要 财务审计和对账的关键。 获取方式 Table: VendInvoiceJour, Field: LedgerVoucher 示例 VOU-10023INV-ACC-992 | |||
| 是否付款冻结 IsPaymentBlocked | 指示发票当前是否被冻结付款的标识。 | ||
| 描述 用于标识发票是否处于暂停状态的布尔值。在 Dynamics 365 中,这通常源自 这是“付款冻结与摩擦分析”的核心驱动因素,用于凸显流程中断情况。 为何重要 识别即时的摩擦点和人工干预环节。 获取方式 Table: VendTrans, Field: Approved (inverted) or specialized Hold fields 示例 truefalse | |||
| 现金折扣日期 CashDiscountDate | 为了获得折扣而必须付款的最后日期。 | ||
| 描述 获取提前付款激励的截止日期。在 Dynamics 365 中,即为 该属性为“现金折扣获取绩效”仪表板提供支持,使组织能够量化错失的成本节约机会。 为何重要 直接影响流程的财务效率 KPI。 获取方式 Table: VendInvoiceJour or VendTrans, Field: CashDiscDate 示例 2023-10-102023-10-20 | |||
| 货币 Currency | 发票的币种代码。 | ||
| 描述 发票开具币种的 ISO 代码。在 Dynamics 365 中,即为 如果需要进行多币种标准化,这对于在“活动金额”映射中统一金额至关重要。 为何重要 解读财务数值所需的背景信息。 获取方式 Table: VendInvoiceJour, Field: CurrencyCode 示例 美元EURGBP | |||
应付账款付款处理活动
| 活动 | 描述 | ||
|---|---|---|---|
| 付款已生成 | 系统生成付款文件(EFT, ISO20022)或打印支票。日记账行上的付款状态更新为“已发送”或“已生成”。 | ||
| 为何重要 支持“审批至执行”滞后时间 KPI。它确认了付款指令已经生成。 获取方式 LedgerJournalTrans.PaymentStatus 变更为“已发送/已接收”。通常从行更新推断得出。 捕获 对比 PaymentStatus 字段变更前后 事件类型 inferred | |||
| 付款已过账 | 付款日记账已过账至总账,结算了发票并核销了供应商余额。这标志着财务流程的完成。 | ||
| 为何重要 “平均发票至付款周期时间”的最后一项活动。它确认了现金减少的会计分录已定稿。 获取方式 LedgerJournalTrans 已过账。更新 VendTrans 以显示结算。实际事件是日记账的过账。 捕获 执行交易 X 时记录 事件类型 explicit | |||
| 付款日记账已创建 | 发票被选中并添加到付款日记账行中。这表明了付款意图,并通常会启动付款复核工作流。 | ||
| 为何重要 标记从债务阶段向现金支出处理阶段的过渡。用于衡量付款执行的前置时间。 获取方式 LedgerJournalTrans.CreatedDateTime。发票通过 MarkedInvoice 字段或结算表进行关联。 捕获 在 LedgerJournalTrans 中创建记录时记录 事件类型 explicit | |||
| 发票已与采购订单匹配 | 系统成功将发票行与采购订单或产品收据连接起来。该活动标志着发票已通过采购订单验证。 | ||
| 为何重要 对于“首检 PO 匹配率”这一 KPI 至关重要。它能区分自动化处理与需要人工干预的发票。 获取方式 VendInvoiceInfoLine.PurchId 和 VendInvoiceInfoTable.MatchStatus。在 MatchStatus 变为 Passed 时推断。 捕获 对比 MatchStatus 字段变更前后 事件类型 inferred | |||
| 发票已创建 | 系统中待处理供应商发票记录的初始创建。这标志着发票进入了 Dynamics 365 工作流,可能是通过手动录入或数据实体导入。 | ||
| 为何重要 确立流程提前期计算的起点。它使企业能够衡量发票在被处理或过账前在系统中滞留了多久。 获取方式 VendInvoiceInfoTable.CreatedDateTime 或 VendInvoiceInfoTable.RecId 创建时间戳。这代表待处理供应商发票抬头。 捕获 在 VendInvoiceInfoTable 中创建记录时记录 事件类型 explicit | |||
| 发票已审批 | 待处理发票的工作流实例达到已完成或已获批状态。发票现在可以过账到总账。 | ||
| 为何重要 计算平均审批提前期。此处的延迟会直接影响企业获取提前付款折扣的能力。 获取方式 WorkflowTrackingStatusTable.CreatedDateTime,其中 TrackingStatus 为 Completed。或者 VendInvoiceInfoTable.RequestStatus 等于 Approved。 捕获 工作流实例完成时记录 事件类型 explicit | |||
| 发票已过账 | 发票已过账至总账,在系统中产生了负债。记录从待处理表转移到已过账事务表。 | ||
| 为何重要 表示债务在财务上得到确认的关键里程碑。此活动完成后,发票即可被选中进行付款。 获取方式 在 VendInvoiceJour 和 VendTrans 中创建记录。TransDate 代表过账日期。 捕获 执行交易 X 时记录 事件类型 explicit | |||
| 付款日记账已核准 | 付款日记账工作流已获批,授权生成付款。这是资金准备划转前的最后一项检查。 | ||
| 为何重要 将付款的行政准备工作与授权瓶颈环节区分开来。 获取方式 WorkflowTrackingStatusTable 关联至 LedgerJournalTable (Header) ID。状态为 Completed。 捕获 工作流实例完成时记录 事件类型 explicit | |||
| 发票匹配失败 | 匹配过程识别出发票与采购订单/收据之间存在不一致(价格或数量偏差)。这通常会导致流程暂停,直到问题解决。 | ||
| 为何重要 识别匹配流程中的具体摩擦点。为“采购订单匹配与差异趋势”仪表板提供支持。 获取方式 VendInvoiceInfoTable.MatchStatus 变为 Failed 或 Discrepancy。在 VendInvoiceInfoLine 匹配偏差中也可见。 捕获 对比 MatchStatus 字段变更前后 事件类型 inferred | |||
| 发票已提交审批 | 待处理发票被提交至工作流引擎进行复核。这标志着流程从数据录入/匹配阶段进入了授权阶段。 | ||
| 为何重要 标记审批周期时间的起点。对于分析内部管理层级的执行效率至关重要。 获取方式 WorkflowTrackingStatusTable.CreatedDateTime,其中 ContextTableId 等于 VendInvoiceInfoTable ID 且状态为 Submitted。 捕获 工作流实例发起时记录 事件类型 explicit | |||
| 发票已更新 | 记录过账前对发票抬头或行项目所做的更改。频繁的更新可能预示着数据提取问题,或在核验过程中需要人工修正。 | ||
| 为何重要 高频更新通常暗示存在返工循环或源头数据质量差(如 OCR 识别错误)。这为“返工与数据准确性监控”提供了支持。 获取方式 如果已启用,则使用 VendInvoiceInfoTable 上的数据库日志 (SysDatabaseLog);或者在轮询频率较高的情况下,从 ModifiedDateTime 的变更推断得出。 捕获 在后续提取中对比 ModifiedDateTime 事件类型 inferred | |||
| 已应用付款锁定 | 供应商交易被暂停,导致其无法被选中进入付款建议。这通常发生在存在争议时的手动处理。 | ||
| 为何重要 支持付款锁定和摩擦点分析。揭示拖慢现金流出的手动干预环节。 获取方式 VendTrans.Approved 标志设为 No,或特定的 OnHold 状态字段已填充。需要追踪 VendTrans 的更新。 捕获 对比状态字段变更前后 事件类型 inferred | |||
提取指南
步骤
访问 Data Management 工作区:登录 Microsoft Dynamics 365 Finance 环境,进入“工作区”并选择“数据管理”。这是配置数据导出项目的中心枢纽。
创建导出项目:点击“导出”卡片以创建新项目。为项目命名,例如 ProcessMining_AP_Export。在“目标数据格式”字段中,选择目标格式(例如用于 BYOD 的 Azure SQL DB 或基于文件的 CSV 导出)。
添加数据实体:逐个将以下标准数据实体添加到项目中:VendorInvoiceHeaderEntity(待处理发票)、VendorInvoiceLineEntity(发票行)、VendorInvoiceJournalHeaderEntity(已过账发票)、VendorPaymentJournalLineEntity(付款)以及 WorkflowHistoryEntity(审批日志)。如果默认不提供 WorkflowHistoryEntity,您可能需要启用自定义实体或公开特定系统实体进行导出。
配置实体过滤器:针对每个实体,点击“过滤器”图标。应用过滤器以限制相关的 CompanyInfo (DataAreaId),并在 CreatedDateTime 或 InvoiceDate 字段上设置日期范围,以仅提取分析期间(如过去 12 个月)的数据。
设置定期导出:为确保 event log 保持最新,请创建一个定期数据作业。定义频率(如每天或每小时),并在支持的情况下启用增量推送 (Incremental push)。这通过仅导出变更记录来降低系统负载。
执行初始导出:点击“立即导出”首次手动运行项目。监控“执行摘要”以确保所有记录均成功导出且无错误。
转换数据:数据导出到目标(Azure SQL 或文件)后,使用“查询”部分提供的 SQL 脚本连接这些表。此转换逻辑将分散的实体记录整合为单一的、按时间顺序排列的 event log。
映射属性:根据 Process Mining 工具的要求,确保最终数据集将 InvoiceNumber 映射为 Case ID,将 EventTime 映射为 Timestamp,将 Activity 映射为 Activity Name。
验证并上传:运行下列验证检查以确认数据准确性。验证完成后,将最终结果导出为 CSV 或 Parquet 文件并上传至 ProcessMind。
配置
- 实体选择:在过账前的流程步骤中,请使用 VendorInvoiceHeaderEntity 和 VendorInvoiceLineEntity。针对已过账的正式法律单据,请使用 VendorInvoiceJournalHeaderEntity。付款跟踪则使用 VendorPaymentJournalLineEntity。
- 增量推送 (Incremental Push):在 Data Management 项目中开启此设置,以便在初始全量加载后仅导出新增或修改的记录。这对系统性能至关重要。
- 日期范围:按 InvoiceDate >= [开始日期] 进行过滤。避免导出无限制的数据,否则可能导致系统超时。
- 公司过滤器:D365 是一个多实体系统。除非是为了进行跨公司分析,否则请务必按 DataAreaId 进行过滤,以避免混淆不同法人实体的数据。
- 工作流历史 (Workflow History):标准工作流历史实体可能非常庞大。请确保仅导出与 VendInvoice 类型相关的历史记录,以控制数据量。
a 查询示例 config
/*
SQL Transformation Script for D365 Finance AP Process
Assumes data is loaded into Staging tables in a SQL environment (BYOD/Data Lake)
*/
SELECT
I.InvoiceNumber AS [InvoiceNumber],
'Invoice Created' AS [Activity],
I.CreatedDateTime AS [EventTime],
I.DataAreaId AS [CompanyCode],
I.InvoiceAccount AS [VendorAccount],
I.InvoiceAmount AS [InvoiceAmount],
I.CurrencyCode AS [Currency],
'D365 FO' AS [SourceSystem],
GETDATE() AS [LastDataUpdate]
FROM Staging_VendorInvoiceHeaderEntity I
UNION ALL
/* Capture updates to invoice headers */
SELECT
I.InvoiceNumber,
'Invoice Updated',
I.ModifiedDateTime,
I.DataAreaId,
I.InvoiceAccount,
I.InvoiceAmount,
I.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorInvoiceHeaderEntity I
WHERE I.ModifiedDateTime > I.CreatedDateTime
UNION ALL
/* Invoice Matching Activities */
SELECT
I.InvoiceNumber,
'Invoice Matched to PO',
I.ModifiedDateTime,
I.DataAreaId,
I.InvoiceAccount,
I.InvoiceAmount,
I.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorInvoiceHeaderEntity I
WHERE I.MatchStatus = 'Matched' -- Adjust value based on system config
UNION ALL
SELECT
I.InvoiceNumber,
'Invoice Match Failed',
I.ModifiedDateTime,
I.DataAreaId,
I.InvoiceAccount,
I.InvoiceAmount,
I.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorInvoiceHeaderEntity I
WHERE I.MatchStatus = 'Failed'
UNION ALL
/* Workflow Activities */
SELECT
RelatedContext AS InvoiceNumber,
CASE
WHEN Status = 'Submitted' THEN 'Invoice Submitted for Approval'
WHEN Status = 'Approved' THEN 'Invoice Approved'
ELSE 'Workflow Activity'
END AS [Activity],
CreatedDateTime AS [EventTime],
DataAreaId,
NULL AS [VendorAccount],
NULL AS [InvoiceAmount],
NULL AS [Currency],
'D365 FO',
GETDATE()
FROM Staging_WorkflowHistoryEntity
WHERE ContextTableId = 12345 -- Replace with TableId for VendInvoiceInfoTable
AND Status IN ('Submitted', 'Approved')
UNION ALL
/* Invoice Posted */
SELECT
J.InvoiceNumber,
'Invoice Posted',
J.PostedDateTime,
J.DataAreaId,
J.InvoiceAccount,
J.InvoiceAmount,
J.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorInvoiceJournalHeaderEntity J
UNION ALL
/* Payment Block */
SELECT
I.InvoiceNumber,
'Payment Block Applied',
I.ModifiedDateTime,
I.DataAreaId,
I.InvoiceAccount,
I.InvoiceAmount,
I.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorInvoiceJournalHeaderEntity I
WHERE I.OnHold = 'Yes'
UNION ALL
/* Payment Activities */
SELECT
J.InvoiceId AS [InvoiceNumber],
'Payment Journal Created' AS [Activity],
P.CreatedDateTime AS [EventTime],
P.DataAreaId,
P.AccountDisplayValue AS [VendorAccount],
P.DebitAmount AS [InvoiceAmount],
P.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorPaymentJournalLineEntity P
JOIN Staging_VendorInvoiceJournalHeaderEntity J ON P.InvoiceId = J.InvoiceNumber AND P.DataAreaId = J.DataAreaId
UNION ALL
SELECT
J.InvoiceId AS [InvoiceNumber],
'Payment Journal Approved' AS [Activity],
P.ModifiedDateTime AS [EventTime],
P.DataAreaId,
P.AccountDisplayValue,
P.DebitAmount,
P.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorPaymentJournalLineEntity P
JOIN Staging_VendorInvoiceJournalHeaderEntity J ON P.InvoiceId = J.InvoiceNumber AND P.DataAreaId = J.DataAreaId
WHERE P.PaymentStatus = 'Approved'
UNION ALL
SELECT
J.InvoiceId AS [InvoiceNumber],
'Payment Generated' AS [Activity],
P.ModifiedDateTime AS [EventTime],
P.DataAreaId,
P.AccountDisplayValue,
P.DebitAmount,
P.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorPaymentJournalLineEntity P
JOIN Staging_VendorInvoiceJournalHeaderEntity J ON P.InvoiceId = J.InvoiceNumber AND P.DataAreaId = J.DataAreaId
WHERE P.PaymentStatus = 'Sent'
UNION ALL
SELECT
J.InvoiceId AS [InvoiceNumber],
'Payment Posted' AS [Activity],
P.PostedDate AS [EventTime],
P.DataAreaId,
P.AccountDisplayValue,
P.DebitAmount,
P.CurrencyCode,
'D365 FO',
GETDATE()
FROM Staging_VendorPaymentJournalLineEntity P
JOIN Staging_VendorInvoiceJournalHeaderEntity J ON P.InvoiceId = J.InvoiceNumber AND P.DataAreaId = J.DataAreaId
WHERE P.IsPosted = 'Yes' 步骤
验证 BYOD 连接性:确保您已安装 SQL Server Management Studio (SSMS) 或类似工具,并能连接到为 Dynamics 365 环境配置的 BYOD (Bring Your Own Database) 目标 Azure SQL 数据库。
确认实体导出:进入 Dynamics 365 的“数据管理”工作区。确认以下实体(或底层表)已配置导出到 BYOD 数据库:
VendInvoiceInfoTable(待处理发票)、VendInvoiceInfoLine(待处理行)、VendInvoiceJour(已过账发票)、VendTrans(供应商交易)、LedgerJournalTrans(日记账行)、LedgerJournalTable(日记账头)以及WorkflowTrackingStatusTable(工作流历史)。配置导出作业:如果这些表当前未导出,请创建新的导出作业。将“目标数据格式”设置为您的 BYOD SQL 数据库。选择“增量推送 (Incremental Push)”以保持数据同步,避免全量重新导出。运行该作业以填充表数据。
准备 SQL 环境:打开 SSMS 并连接到 BYOD Azure SQL 数据库。打开一个新的查询窗口。
设置参数:在下方提供的脚本顶部找到变量声明部分。更新
@StartDate和@EndDate变量以匹配您要分析的时间段。如果需要过滤特定法人实体,请更新DATAAREAID过滤条件。执行脚本:运行完整的 T-SQL 脚本。该脚本使用
UNION ALL将来自多个表的数据整合为单一的标准 event log 格式。验证数据:检查结果中
InvoiceNumber或EventTime列是否存在空值。确保已过账发票(来自VendInvoiceJour)和待处理发票(来自VendInvoiceInfoTable)均已显示。导出结果:在 SSMS 的结果网格中点击右键,选择“将结果另存为...”。将文件保存为 CSV(逗号分隔)文件。
格式检查:在 Excel 或文本编辑器中打开 CSV,确保日期格式符合 ISO 8601 标准 (YYYY-MM-DD HH:MM:SS)(如果 ProcessMind 有此要求)。如果脚本运行成功,通常不需要进一步转换。
上传至 ProcessMind:将 CSV 文件导入 ProcessMind,将
InvoiceNumber映射为 Case ID,Activity映射为 Activity Name,EventTime映射为 Timestamp。
配置
- 导出策略:针对
LedgerJournalTrans和VendTrans等海量数据表,请使用增量推送 (Incremental Push) 以降低 BYOD 的负载。仅在怀疑数据不一致时才使用全量推送。 - 时区处理:Dynamics 365 以 UTC 格式存储数据,脚本默认也采用 UTC。如果分析需要本地时间,请在脚本中或在 ProcessMind 导入期间使用
DATEADD进行调整。 - 公司过滤:
DataAreaId列代表法人实体。脚本默认提取所有实体的数据。如需过滤特定子公司,请添加WHERE DataAreaId = 'usmf'(示例)。 - 工作流历史:
WorkflowTrackingStatusTable表对于获取审批时间戳至关重要。请确保在 BYOD 导出配置中包含此表,因为它在默认情况下常被忽略。 - 数据保留:请注意 D365 中的清理机制,它可能会删除已完成的工作流历史或已过账的日记账行,这会限制 Process Mining 分析的历史深度。
a 查询示例 sql
/* T-SQL Extraction Script for D365 AP Payment Processing */
/* Tables required: VendInvoiceInfoTable, VendInvoiceInfoLine, VendInvoiceJour, VendTrans, LedgerJournalTrans, LedgerJournalTable, WorkflowTrackingStatusTable */
DECLARE @StartDate DATETIME = '2023-01-01 00:00:00';
DECLARE @EndDate DATETIME = GETDATE();
WITH RawData AS (
/* 1. Invoice Created: Pending Invoice Header Creation */
SELECT
T1.Num AS InvoiceNumber,
'Invoice Created' AS Activity,
T1.CreatedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
T1.InvoiceAccount AS VendorAccount,
T1.DataAreaId AS CompanyCode,
CAST(T1.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
T1.DueDate AS DueDate,
T1.PurchId AS PurchaseOrderNumber,
T1.CreatedBy AS UserId,
T1.VendorName AS VendorName,
T1.DocumentDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.VendInvoiceInfoTable T1
WHERE T1.CreatedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 2. Invoice Updated: Modifications to Pending Invoice */
SELECT
T1.Num AS InvoiceNumber,
'Invoice Updated' AS Activity,
T1.ModifiedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
T1.InvoiceAccount AS VendorAccount,
T1.DataAreaId AS CompanyCode,
CAST(T1.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
T1.DueDate AS DueDate,
T1.PurchId AS PurchaseOrderNumber,
T1.ModifiedBy AS UserId,
T1.VendorName AS VendorName,
T1.DocumentDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.VendInvoiceInfoTable T1
WHERE T1.ModifiedDateTime BETWEEN @StartDate AND @EndDate
AND T1.ModifiedDateTime > T1.CreatedDateTime
UNION ALL
/* 3. Invoice Matched to PO: Line Matching Success */
SELECT
H.Num AS InvoiceNumber,
'Invoice Matched to PO' AS Activity,
L.ModifiedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
H.InvoiceAccount AS VendorAccount,
H.DataAreaId AS CompanyCode,
CAST(H.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
H.DueDate AS DueDate,
H.PurchId AS PurchaseOrderNumber,
L.ModifiedBy AS UserId,
H.VendorName AS VendorName,
H.DocumentDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.VendInvoiceInfoLine L
JOIN dbo.VendInvoiceInfoTable H ON L.TableRefId = H.TableRefId AND L.DataAreaId = H.DataAreaId
WHERE L.MatchStatus = 1 /* 1 usually denotes Matched/Passed in enum */
AND L.ModifiedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 4. Invoice Match Failed: Line Matching Discrepancy */
SELECT
H.Num AS InvoiceNumber,
'Invoice Match Failed' AS Activity,
L.ModifiedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
H.InvoiceAccount AS VendorAccount,
H.DataAreaId AS CompanyCode,
CAST(H.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
H.DueDate AS DueDate,
H.PurchId AS PurchaseOrderNumber,
L.ModifiedBy AS UserId,
H.VendorName AS VendorName,
H.DocumentDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.VendInvoiceInfoLine L
JOIN dbo.VendInvoiceInfoTable H ON L.TableRefId = H.TableRefId AND L.DataAreaId = H.DataAreaId
WHERE L.MatchStatus = 2 /* 2 usually denotes Failed in enum */
AND L.ModifiedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 5. Invoice Submitted for Approval: Workflow Submission */
SELECT
T1.Num AS InvoiceNumber,
'Invoice Submitted for Approval' AS Activity,
W.CreatedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
T1.InvoiceAccount AS VendorAccount,
T1.DataAreaId AS CompanyCode,
CAST(T1.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
T1.DueDate AS DueDate,
T1.PurchId AS PurchaseOrderNumber,
W.User AS UserId,
T1.VendorName AS VendorName,
T1.DocumentDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.WorkflowTrackingStatusTable W
JOIN dbo.VendInvoiceInfoTable T1 ON W.ContextRecId = T1.RecId
WHERE W.TrackingStatus = 1 /* Submitted */
AND W.ContextTableId = 1425 /* TableId for VendInvoiceInfoTable, adjust if different in version */
AND W.CreatedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 6. Invoice Approved: Workflow Completion */
SELECT
T1.Num AS InvoiceNumber,
'Invoice Approved' AS Activity,
W.CreatedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
T1.InvoiceAccount AS VendorAccount,
T1.DataAreaId AS CompanyCode,
CAST(T1.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
T1.DueDate AS DueDate,
T1.PurchId AS PurchaseOrderNumber,
W.User AS UserId,
T1.VendorName AS VendorName,
T1.DocumentDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.WorkflowTrackingStatusTable W
JOIN dbo.VendInvoiceInfoTable T1 ON W.ContextRecId = T1.RecId
WHERE W.TrackingStatus = 2 /* Completed/Approved */
AND W.ContextTableId = 1425
AND W.CreatedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 7. Invoice Posted: Creation of VendInvoiceJour */
SELECT
J.InvoiceId AS InvoiceNumber,
'Invoice Posted' AS Activity,
J.CreatedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
J.InvoiceAccount AS VendorAccount,
J.DataAreaId AS CompanyCode,
CAST(J.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
J.DueDate AS DueDate,
J.PurchId AS PurchaseOrderNumber,
J.CreatedBy AS UserId,
J.InvoicingName AS VendorName,
J.InvoiceDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.VendInvoiceJour J
WHERE J.CreatedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 8. Payment Block Applied: Updated on VendTrans */
SELECT
J.InvoiceId AS InvoiceNumber,
'Payment Block Applied' AS Activity,
VT.ModifiedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
J.InvoiceAccount AS VendorAccount,
J.DataAreaId AS CompanyCode,
CAST(J.InvoiceAmount AS DECIMAL(18,2)) AS InvoiceAmount,
J.DueDate AS DueDate,
J.PurchId AS PurchaseOrderNumber,
VT.ModifiedBy AS UserId,
J.InvoicingName AS VendorName,
J.InvoiceDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.VendTrans VT
JOIN dbo.VendInvoiceJour J ON VT.Invoice = J.InvoiceId AND VT.AccountNum = J.InvoiceAccount AND VT.DataAreaId = J.DataAreaId
WHERE VT.Approved = 0 /* 0 indicates Not Approved/Blocked */
AND VT.ModifiedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 9. Payment Journal Created: Line added to Journal */
SELECT
LJT.Invoice AS InvoiceNumber,
'Payment Journal Created' AS Activity,
LJT.CreatedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
LJT.AccountNum AS VendorAccount,
LJT.DataAreaId AS CompanyCode,
CAST(LJT.AmountCurCredit AS DECIMAL(18,2)) AS InvoiceAmount,
NULL AS DueDate,
NULL AS PurchaseOrderNumber,
LJT.CreatedBy AS UserId,
NULL AS VendorName,
LJT.TransDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.LedgerJournalTrans LJT
WHERE LJT.AccountType = 2 /* Vendor */
AND LJT.Invoice IS NOT NULL AND LJT.Invoice <> ''
AND LJT.CreatedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 10. Payment Journal Approved: Workflow on Journal Header */
SELECT
LJT.Invoice AS InvoiceNumber,
'Payment Journal Approved' AS Activity,
LJH.ModifiedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
LJT.AccountNum AS VendorAccount,
LJT.DataAreaId AS CompanyCode,
CAST(LJT.AmountCurCredit AS DECIMAL(18,2)) AS InvoiceAmount,
NULL AS DueDate,
NULL AS PurchaseOrderNumber,
LJH.ModifiedBy AS UserId,
NULL AS VendorName,
LJT.TransDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.LedgerJournalTable LJH
JOIN dbo.LedgerJournalTrans LJT ON LJH.JournalNum = LJT.JournalNum AND LJH.DataAreaId = LJT.DataAreaId
WHERE LJH.WorkflowApprovalStatus = 2 /* Approved */
AND LJT.AccountType = 2
AND LJT.Invoice IS NOT NULL AND LJT.Invoice <> ''
AND LJH.ModifiedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 11. Payment Generated: Payment Status Changed to Sent */
SELECT
LJT.Invoice AS InvoiceNumber,
'Payment Generated' AS Activity,
LJT.ModifiedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
LJT.AccountNum AS VendorAccount,
LJT.DataAreaId AS CompanyCode,
CAST(LJT.AmountCurCredit AS DECIMAL(18,2)) AS InvoiceAmount,
NULL AS DueDate,
NULL AS PurchaseOrderNumber,
LJT.ModifiedBy AS UserId,
NULL AS VendorName,
LJT.TransDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.LedgerJournalTrans LJT
WHERE LJT.PaymentStatus = 2 /* Sent/Generated */
AND LJT.AccountType = 2
AND LJT.Invoice IS NOT NULL AND LJT.Invoice <> ''
AND LJT.ModifiedDateTime BETWEEN @StartDate AND @EndDate
UNION ALL
/* 12. Payment Posted: Journal Line Posted */
SELECT
LJT.Invoice AS InvoiceNumber,
'Payment Posted' AS Activity,
LJT.ModifiedDateTime AS EventTime,
'D365 FO' AS SourceSystem,
GETDATE() AS LastDataUpdate,
LJT.AccountNum AS VendorAccount,
LJT.DataAreaId AS CompanyCode,
CAST(LJT.AmountCurCredit AS DECIMAL(18,2)) AS InvoiceAmount,
NULL AS DueDate,
NULL AS PurchaseOrderNumber,
LJT.ModifiedBy AS UserId,
NULL AS VendorName,
LJT.TransDate AS InvoiceDate,
'Unknown' AS Department
FROM dbo.LedgerJournalTrans LJT
WHERE LJT.Posted = 1 /* Posted */
AND LJT.AccountType = 2
AND LJT.Invoice IS NOT NULL AND LJT.Invoice <> ''
AND LJT.ModifiedDateTime BETWEEN @StartDate AND @EndDate
)
SELECT *
FROM RawData
WHERE InvoiceNumber IS NOT NULL AND InvoiceNumber <> ''
ORDER BY InvoiceNumber, EventTime;