将数据库输出映射为 EDI 810 发票
Version 24.2.8986
将数据库输出映射为 EDI 810 发票
概述
知行之桥包含强大的工具,可以将从后端数据库中查询目标数据并将其映射为一个出站的 EDI 文件(X12,EDIFACT 等)。本文将逐步介绍从创建数据库到 EDI 的工作流的过程,重点为生成一个 X12 810 文件(发票)。页面底部提供了所用的 Amazon 示例发票。
本文中描述的方法和原理也适用于生成其它 EDI 文档,但从数据库中提取的特定数据以及映射值之间的关系可能存在差异。
本文从如何在知行之桥中完成映射的概述开始,然后逐步完成映射工作流的每一步。本页底部包含本文中使用的示例数据(数据库结构,输出文件以及生成的 810 文件)。
知行之桥中的 EDI 映射
将数据库数据提取为 XML
知行之桥使用 XML 作为通用格式,以完成数据转换和操作。所有 EDI 映射工作流涉及将源数据(本例中为数据库数据)和目标数据(本例中为 EDI 文件)转换为 XML。
所有从数据库(或类数据库的应用程序)提取数据的端口都会自动将输出数据格式化为 XML 文件。因此,从数据库中提取的数据可以立即进行映射或转换。本文将使用 Database 端口,配置有 MySQL 驱动程序,与 MySQL 数据库交互。
提取 810 发票相关的数据
通常会根据采购订单将发票发送给交易伙伴。当制造商公司接收到请求一组制成品的采购订单时,制造商公司使用发票响应,以支付所请求的货物。
因此,用来生成发票的数据通常来自之前接收到的采购订单中。本文假设输入的采购订单被自动插入到数据库中,所以采购订单数据库表保存着与 810 发票相关的数据。当为映射工作流配置 Database 端口时,Database 端口将指向保存采购订单数据的表。
采购订单可以包含多个订单行,并且典型的数据库设置会将订单行数据储存在与 PurchaseOrders
表分开的 LineItems
表中。LineItems
表具有 PurchaseOrders
表的外键,以便知道哪些订单行与哪个采购订单关联,但是必须从两个表中提取数据才能检索所有必要的信息,以填充 810 发票。
文中专门用于配置 Database 端口的部分将包括同时从 PurchaseOrders
表和 LineItems
表(具有合适的外键关系)提取数据的必要步骤。
将 EDI 文件表示为 XML
为了将从数据库中提取的 XML 数据映射为 EDI 文档,EDI 文档必须也可以表示为 XML。知行之桥包括很多种可以实现 EDI 和 XML 格式(X12,EDIFACT 等)相互转换的端口。本文重点介绍映射 X12 文档,因此 X12 端口将用于生成目标 810 文档的 XML 表示。
在创建映射工作流之前,有一个示例输出文档很重要(例如示例 810)。该示例文档将用作为映射步骤创建 XML 模型。
转换 XML 结构
一旦源格式和目标格式都表示为 XML ,强大的 XML Map 端口可以用来将一个 XML 结构转换为另一个。
XML Map 端口需要一个示例源文件和一个示例目标文件,分别代表了起始的 XML 结构和最终的 XML 结构。从数据库中提取的 XML 输出将会作为源文件,X12 810 文档的 XML 表示(通过将示例 810 通过 X12 端口处理)将会作为目标文件。
一旦指定源结构和目标结构,XML Map 端口的可视化设计器将会被两个结构填充。源文件中的元素可以被拖拽到目标文件的元素上,以在两者之间创建映射关系。映射这一步需要理解 EDI 结构,这样合适的元素才能包括在输出文件中。
XML Map 端口包括格式化器,条件逻辑,甚至是自定义的脚本来在映射过程中操作和计算数据。
一旦映射关系创建,XML Map 端口可以自动将匹配源 XML 结构的文件转换为目标 XML 结构。在本例中,这意味着从数据库中提取的数据将会自动转换为 XML 810 文件的 XML 模型。最后一步是采用 810 文件的 XML 模型并将其换转为实际的 810 文档,通过 X12 端口可以轻松完成。
创建映射工作流
本节包含在知行之桥中创建工作流的每一步,检索数据库输出并将其映射到 810 发票。
步骤 1:Database 端口
映射工作流的第一步是配置 Database 端口 ,并从 MySQL 后端提取相关数据。
建立连接
在应用程序的工作流页面,将 Database 端口实例拖拽到工作区中。对于生产环境的工作流,Database 端口实例的命名应该包含目标数据库(本例中为 MySQL)和提取和推送数据库中数据的上下文信息(例如:MySQL_Invoice_tradingPartner);在这个工作流中,为了简单起见,端口实例命名为 Database
。
Database 端口是一个可以与多种类型数据库交互的通用端口,因此必须配置有合适的数据库驱动,以连接至特定的数据库。知行之桥内含 MySQL 驱动,作为应用程序的一部分,因此无需其它的步骤来安装 MySQL 驱动,Database 端口可以读取它。
选定 MySQL 驱动后,Database 端口设置界面自动填充目标数据库所需的连接设置。输入所需的连接属性(或连接字符串)以连接 MySQL 数据库。
测试连接 按钮可以用来验证端口与目标数据库是否建立起连接。
创建输出映射
一旦连接建立,就可以创建输出映射来从数据库中提取相关的数据。和在提取 810 发票相关的数据中一样,输出映射必须从父表 PurchaseOrders
和子表 LineItems
中提取数据。
在 Database 端口设置中,找到映射部分并选择输出
,使用+ 按钮来创建新的输出映射,将会显示数据库中表的列表。应先选择父表(有采购订单数据),再选择子表(有订单行数据)。在本例中,采购订单表是 test_po_line_items
,选择该表时会显示出映射编辑器:
编辑器允许在应检索的列中选择表;本文在输出 XML 中包括表的所有列。
表中的一列为 Processed
列,如果该记录没有被处理,则会存值为 0,如果被处理过则为 1。当采购订单被插入表中,Processed
列将被设为 0。输出映射应只提取 Processed
列值为 0 的记录,并且在成功提取记录后应将该值更新为 1。
要完成这步,首先应在过滤器中设置提取 Processed
=0 的记录。在映射编辑器的过滤器部分,增加一条新规则:
- 第一个(左侧)下拉列表是要检查的列;本例中为
Processed
- 第二个(中间)下拉列表是逻辑运算符,本例中为
等于
- 最后一个(右侧)输入的是需要和列比较的值,本例中为 0
除了根据Processed
列来过滤记录,该列需要被更新,这样一来记录不会被重复提取。映射编辑器底部的高级
部分允许特定一列,当成功从数据库中读取行时,该值将被更新。
这种情况下,Processed
列应被更新为 1:
现在,合适的记录将会从 test_purchase_orders
表中被提取,输出映射应该也做好配置,将与每个采购订单关联的订单行提取出来。本例中,订单行数据保存在 test_po_line_items
表中。
在映射编辑器的顶部左侧,点击 + 按钮在映射中添加一个新的表。选择合适的子表到映射中:
映射编辑器将自动使用左侧面板中的表树结构进行更新。和 test_purchase_orders
表类似,test_po_line_items
特定的列可以选择性地输出;本文包括所有的表列。
当 Database 端口从 test_purchase_orders
表中提取记录时,它还会从 test_po_line_items
表中提取记录。只有与当前采购订单关联的订单行会被提取,所以必须在该子表上应用WHERE
约束。
在本例中, test_po_line_items
表中的 PONumber
列对应 test_purchase_orders
表中的 PONumber
。只有订单行中的 PONumber
与采购订单中的 PONumber
匹配,订单行才会包括在采购订单的输出记录中。
要完成该步,添加一条新规则到 test_po_line_items
映射的过滤器部分:
- 第一个下拉列表(左侧)是子表中需要检查的列;本例中为
PONumber
- 第二个下拉列表(中间)应为
等于
- 最后一个(右侧)的输入可以通过单击下拉箭头并选择
REF
设置为参考父表($
符号出现表示引用) - 最后(右侧)的输入应该设置为父表中的列以进行比较;在本例中,应为
PONumber
输入映射现在就配置完了,可以在 Database 端口中保存。
一旦输入映射被保存,数据可以以两种方式从数据库中被提取。如果 Database 端口自动化
页面下接收自动化
被启用,端口将根据接收间隔
自动尝试提取未处理的订单(和关联的订单行)。也可以导航到输出
界面通过单击接收
来手动提取记录。
输出映射为 XML
在输出映射创建后,Database 端口将此输出映射表示为 XML。要查看输出映射的 XML 模型,请单击配置的输出映射右侧的 </> 按钮:
当 Database 端口从数据库中提取数据,它将使用检索到的值来使用此结构填充 XML 文档。请注意,XML 文件中的子结构可能会重复;例如如果为单个订单提取多个订单行, test_po_line_items
表的 XML 子级将会对每个订单行进行重复。
该 XML 结构最终需要被映射为表示 X12 810 发票的 XML,产生的映射 XML 可以直接转换为 EDI 文档。
注意:本文中使用的输出映射可以在本页底部的示例数据部分找到。
步骤 2:X12 端口
X12 端口在映射工作流中充当两个角色。首先,它将用于生成示例 810 发票的 XML 表示;该 XML 示例文件将会在之后用到,在 XML Map 端口中,将数据库输出映射为 EDI 结构。此外,X12 端口将会在工作流中最后一步中,将 XML Map 端口生成的 XML 转换为 X12 文档。
在工作流页面,将一个 X12 端口实例拖拽到工作区中。X12 端口示例的命名一般应包括发送 X12 文档的交易伙伴的名称;在此工作流中,为了简单起见,将该实例命名为 X12
:
上传测试文件
X12 端口的上传测试文件特性简化了为目标 EDI 文档生成 XML 模型的过程。打开 X12 端口的设置并导航到输入
页面;更多下拉菜单包括上传测试文件选项:
在磁盘中浏览查找一个示例 810 发票文件并上传到端口。X12 端口将在内部生成该文件的一个 XML 模型,XML Map 端口可以自动检测到该模型。因为模型是内部储存的,端口的外观和配置保持不变。
注意:本例中使用的 810 文件可以在本页底部的示例数据部分找到。
配置 X12 端口
除了创建一个示例 XML 模型,X12 端口也被用于将 XML Map 端口映射的 XML 转换为输出的 EDI 文件。除了轻松地将 XML 格式转换为 X12 格式,X12 端口也根据端口中的配置添加交换和功能组数据到文档中。因此,根据特定接收出站的 X12 810 文件的交易伙伴信息去配置 X12 端口是很重要的。
在 X12 端口的设置界面,转换类型 特性应设置为 XML 转换为 X12
。当处于该模式下,输入 X12 端口的文件应该为结构是 EDI 文档的 XML。使用前一步 XML Map 端口创建测试文件选项确保输入的 XML 与该特定结构匹配。
X12 端口也根据端口中的配置填充交换和功能组的值。最少应设置以下这些值:
- 发送方 ID - 对于发出 EDI 文档,这就是用户的 ID(如果该值需要限定,那么发送方 ID 限定符应设置为限定值)
- 接收方 ID - 对于发出 EDI 文档,这是交易伙伴的 ID(如果该值需要限定,那么接收方 ID 限制符应设为限定值)
- 测试指示符 - 表明发出的 EDI 文档当作生产数据还是测试数据
交易伙伴可能需要进一步的交换(ISA)和功能组(GS)信息,以成功接收 810;请与交易伙伴沟通清楚需要哪些头部元素。所有 X12 端口可配置的属性记录在此处。
步骤 3:XML Map 端口
现在 Database 端口和 X12 端口已经分别生成了输入和输出数据的模型,XML Map 端口需要将一个 XML 结构转换为另一个。
将一个 XML Map 端口实例拖拽到工作流中,之后将 Database 端口连接到 XML Map 端口,将 XML Map 端口连接到 X12 端口。
注意:请在工作流工作区的右下角保存更改(关闭所有端口的配置以查看蓝色的保存图标)。
配置 XML Map 端口
在 XML Map 端口的配置界面,找到源文件和目标文件的下拉菜单。XML Map 端口应该从 Database 端口的输出映射检测 XML 模型,将其作为可用的源文件,将 X12 端口的测试文件作为可用的目标文件。如果这些选项都不可用,请验证是否正确保存了测试文件和输出映射,是否已在工作流工作区中连接了端口,以及是否通过工作流页面右下角的蓝色保存图标保存了工作流更改。
一旦指定源文件和目标文件,XML Map 可视化设计器将会自动使用输出映射和示例 X12 810 文件的 XML 结构填充。
如果在目标结构中的 Interchange 和 FunctionalGroup 元素包含 Meta 元素,则可以安全地删除它们;当将 XML 转换为 EDI 时,X12 端口会将相关的元数据应用于 ISA 和 GS 段。
理解 XML 结构
要在 XML Map 端口创建正确的映射关系需要理解如何使用 XML 表示源和目标结构。
首先,在结构中与两种 XML 元素(节点)。父
节点由子节点组成但是没有值。Leaf
节点由值组成但是没有子节点。父节点可以使用旁边的 + 或 - 展开(以展示子节点)或收缩(以隐藏子节点)。
在 XML 数据库中,每个父节点代表一张从数据库提取数据的表,每个 Leaf 节点代表了该表中的一列。在 810 XML 中,每个 EDI loop 和 segment 都是一个父节点,每个单独的 EDI element 是一个 Leaf 节点。
创建映射
一旦 XML 端口配置源和目标结构,在可视化设计器中拖拽节点,即可完成映射。
映射可通过主要的两步来创建:
- 在父节点之间创建 Foreach 循环关系
- 在建立的 Foreach Leaf 节点中映射值
创建 Foreach 循环
Foreach 关系意味着在源中某个元素出现一次,在目标中应该创建一个新的 XML 结构。如果源中的 ElementA 映射到目标中的 ElementB,输入文件中每次出现的 ElementA 都会在输出文件中产生 ElementB(以及所有 ElementB 的子级)。
在本例中,每个从采购订单表(PurchaseOrders
)中提取的记录都应该在生成的 EDI 中产生一个新的 Transaction(TX),每个从订单行表(test_po_line_items
)中提取的记录应该生成一个新的 IT1Loop。将 test_purchase_orders 拖拽到 TX-00401-810 元素上,拖拽 test_po_line_items 到 IT1Loop1 元素上:
注意:用来创建目标结构的示例 X12 810 文件可能在映射设计器中显示含有多个 IT1Loop1。由于 Foreach 关系将确保生成正确数量的 IT1Loop1 元素,因此可以安全地保留这些元素中的其中一个,其它均可删除(通过右键单击及节点并选择删除节点
)。
映射 Leaf 节点
一旦 Foreach 关系建立,Leaf 节点的值可以在循环中被映射。映射 Leaf 节点决定了填充由 Forecah 循环创建的 XML 结构的值。
一些 Leaf 节点映射很简单,一些则需要表达式编辑器和脚本编辑器。本节将包含 EDI 文档中每一个常用的 Leaf 节点类型。更多关于多种映射特性的的详情请查阅 XML Map 端口的文档.
简单的 Leaf 节点映射
当源文件中的值应该被直接插入到生成的结果当中,从源中拖拽一个 Leaf 节点到目标中的一个 Leaf 节点上,来映射这些值。该过程需要理解 EDI 目标格式,以及文件中的哪些值需要被包含在生成的 X12 文档中。
例如,X12 810中的 BIG04 元素保存了采购订单编号,来创建发票。自然地,对应了数据库输出的 PONumber 元素。将 PO_Number 节点拖拽到 BIG/BIG04 节点上,以建立该关系:
在映射的目标节点地右边是一个是绿色的 xpath,用来表明映射值的来源(例如PONumber
)。请注意 Leaf 节点 xpaths 与父节点中的 Foreach 节点相关(例如/Items/test_purchase_orders
)。可以将父节点的 xpath 与 Leaf 节点中的 xpath 串联在一起,以在源 XML 中找到映射值:/Items/test_purchase_orders/PONumber
。
在本例中,其它直接的 Leaf 节点映射值包括以下内容:
- PODate -> BIG/BIG03
- CurrencyCode -> CUR/CUR02
- ItemID -> IT1Loop1/IT1/IT107
- Quantity -> IT1Loop1/IT1/IT102
- PricePerUnit -> IT1Loop1/IT1/IT104
- PONumber (again) -> IT1Loop1/IT1/IT111
这些值中的每一个可以简单地从源数据中被拖拽到目标 EDI 文档中,无需修改和条件逻辑。
上下文映射
一些 Leaf 节点映射取决于目标中的其它元素。例如,一个目标 XML 中的 N1Loop1 循环时表示 EDI 交易中的参与方/实体(开票方,运输方,采购方等等)元素的集合。N1Loop1/N101 元素表明了参与方的特定角色,并且参与方的角色决定了应从源 XML 中映射哪些值。
本文中,源数据包括 Ship-To 方和 Remit-To 方的详情。为了在 EDI 输出包含这些数据,应该有两部分独立的 N1Loop1 结构,一个 N1Loop1/N1/N101 设置为 ST
(Ship-To),另一个设置为 RI
(the value for Remit-To)。然后可以通过从源中拖拽 ShipToID 和 RemitToID 来映射每个相应循环的 N1Loop1/N1/N102 值:
其它 Ship_To 数据(ShipToAddr, ShipToZip 等)可以被映射到 N101 为 ST
的 N1Loop1 中的 N2,N3和N4。同样的,其它 Remit-To 数据(RemitToAddr, RemitToZip 等)可以被映射到 N101 为 RI
的 N1Loop1 中。
注意:一些 EDI 循环在目标映射中需要多个不同的节点(例如本节中的 N1Loop1 循环),而其它 EDI 循环在目标映射中仅需要一个节点(例如上一节中的 IT1Loop1 循环)。差异取决于 Foreach 关系是否会自动生成正确数量的输出节点:由于 N1Loop1 节点没有与其关联的 Foreach 关系,因此目标映射需要显式包括正确数量的 N1Loop1 节点。
简单的计算
一些值不是直接从源 XML 中提取的,但是是根据源中一个或多个的值计算得出的。例如,每个 IT1Loop1 循环(即每个订单行)有一个 TXI/TXI02 的元素,代表了适用于该行的税额。源数据包含计算适用于购买的税额所需的所有信息:
- 单价
- 数量
- 税率
然而,计算得到的税率本身不存在于源中,因此必须在 XML Map 端口中计算。
表达式编辑器有格式化器,在映射时可用作处理数据。在本例中,需要 multiply
格式化器来将源数据转换为目标值。
从映射 PricePerUnit 节点到 IT1Loop1/TXI/TXI02 目标节点开始。这是生成合适数学表达式的一个好的开始,因为单位价格是表达式输入值之一。然后,通过目标节点右侧的平板和铅笔
符号打开表达式编辑器:
价格参数应该与数量相乘,来得到行的总费用;将 PricePerUnit 的值通过竖线字符( | )传给 multiply formatter,然后,将 multiply 格式化器的参数设置为 Quantity 源元素中的值: |
注意 Quantity 的xpath
的值应该使用方括号括起来,才能解析为动态值而不是字符串文字。
现在,总费用需要与 TaxPercent 相乘,而且应该与 .01 相乘,从百分数转换为美元值:
保存表达式,映射将根据指定的动态输入自动计算合适的值。
累加计算
输出的810文档有一个 TSD 节点,代表了发票的总金额。总计每行的费用需要一个持续变量,可以在行循环中更新。
需要脚本将值储存在变量中,并在以后的映射中检索这些值。在 ArcScript 中,值储存为 attribute
,items
是可以具有多个属性的对象。使用以下的语法引用对象的属性:item_name.attribute_name
_map 对象是一个特殊的 对象,在整个文档映射中保留属性值。换句话说,大多数 属性(变量)仅保留用于单个节点映射,但是 _map 对象的 属性在映射中的每个节点上都保持不变。
为了计算行的总费用,因此,在行 Foreach 循环(即在 IT1Loop1 循环) 中要设置 _map 对象的一个属性。由于该脚本没有与 IT1Loop1 循环中的任何特定元素相关联,因此应将专用的 Script 元素添加到目标映射。该元素不会出现在生成的 EDI 文档中,但表示正在执行脚本逻辑,以用于映射中的其它用途。
首先,右键单击 IT1Loop1 元素并选择添加代码脚本
来添加一个新的 Script 元素(该元素仅能通过点击和拖动来更换位置):
此脚本需要计算全部费用,可以通过以下公式得到:
(PricePerUnit * Quantity) + (PricePerUnit * Quantity * TaxPercent * .01)
编辑 Script 元素在 ArcScript 中表示该公式:
<arc:set attr="lineItemCost" value="[xpath(PricePerUnit) | multiply([xpath(Quantity)])]" />
<arc:set attr="lineItemTax" value="[lineItemCost | multiply([xpath(TaxPercent)]) | multiply(.01) | round(2)]" />
<arc:set attr="_map.costSum" value="[_map.costSum | def(0) | add([lineItemCost]) | add([lineItemTax])]" />
在每行循环中执行完该脚本之后,_map.costSum 元素将会为每行保存总费用(含税)。要在 TDS/TDS01 元素中引用此值,请单击 TDS 元素右侧的 </> 图标并将 result.text 值设置为先前的属性:
条件映射
一些节点需要条件逻辑去决定是否应该出现在输出中,其中的哪些值应该被设置。例如,ITD 段包括了发票条款的数据,而且只有在条款被指定时才需要在输出的 810 中包含该段。
目标映射中 ITD 旁边的过滤规则
图标可以用来应用一个条件,决定元素(以及它所有的子元素)是否应出现在输出文档中。单击该图标并且在条件编辑器中添加一条规则;本例中采购订单条款将会具有一个前缀,以便我们直知道是否必须在发票中指定条款:
现在 ITD 元素将只有在特殊条款被指定时出现,ITD01 元素需要为条款保存合适的代码。在本例中,以下值应该被用作关联的条款:
- 02 - 加急付款
- 03 - 延迟付款
- 11 - 替代付款模式
输入数据 Terms 元素的值不能通过格式化器转换为 ITD01,因此需要自定义的脚本来决定 ITD01 的映射。点击 ITD01 元素右边的平板和铅笔
图标打开脚本编辑器,下面的脚本可完成上文的那种模式:
<arc:set attr="termsCode" value="" />
<arc:set attr="termsInput" value="[xpath(Terms)]" />
<arc:select value="[termsInput]">
<arc:case value="Expedited Payment">
<arc:set attr="termsCode" value="02" />
</arc:case>
<arc:case value="Delayed Payment">
<arc:set attr="termsCode" value="03" />
</arc:case>
<arc:case value="Alternative Payment Profile">
<arc:set attr="termsCode" value="11" />
</arc:case>
</arc:select>
<arc:set attr='result.text'>[termsCode]</arc:set>
上文的示例使用了 arc:select 关键词,但是使用一系列的 arc:if and arc:else 也可以得到相同的结果,详情请查阅这里
索引映射
目标 XML 中的一些元素需要对 Foreach 循环中的循环次数进行计算。例如,IT1Loop1/IT1/IT101 元素保存着行数,所以需要为采购订单中的每一行进行递增。同样的,Meta/ST02 元素需要为文件中每个采购订单进行递增。
_index 属性是一个特殊的变量,保存着大多数本地 Foreach 循环的索引(即对于嵌套的 Freach 循环,_index 将引用最内层的循环)。只要 Foreach 关系正确地建立,Meta/ST02 和 IT1Loop1/IT1/IT101 可以被设置为以下值,正确地分别对采购订单和订单行进行计数:
[_index]
如果 Foreach 循环中的当前索引与更高级的映射逻辑相关,则此特殊的属性在任何自定义脚本环境中也可用。
在映射中生成一个日期
在目标 XML 中的一些元素根本没有引用源数据。BIG/BIG01 元素代表发票的数据,该值直到当前的映射步骤才可用。
特殊的 now
日期格式化器可以用来根据当前时间生成一个新的日期值。像所有的格式化器一样,在任何节点的映射中都可以使用。
所有的格式化器都需要一个输入的属性来格式化。通常,在 XML 映射期间,输入的属性是使用 xpath
格式化器检索的值(即从源 XML 解析的值)。在本例中,什么值传给了 now
格式化器不重要,因为它总是返回当前的时间。因此,默认的 \_
对象可以作为占位符传递:
注意,传递给now
格式化器的参数定义了日期的输出格式。
计算行和总费用
CTT 段包含计算行的中数量的元素和代表项目总费用的哈希值。计算这些值的方法与累加计算部分描述的类似。
相关的值必须在可用行数据(即 IT1Loop1 部分)的映射部分中进行计算,然后在 CTT 映射中引用。这需要一个自定义的脚本,该脚本将值储存在特殊的 _map对象中。
在 IT1Loop1 循环中(使用 Foreach 关系映射到 test_po_line_items
记录中),右键单击并选择添加代码脚本
来添加新的脚本节点。该脚本将会在每次映射循环时执行,或者换句话说,它将会为每行执行一次。为了计算值,需要对行数和总费用进行求和,然后储存在 _map对象的属性中。
行的数量是通过一个简单的计数器来计算的,而费用可以使用累加计算部分中使用的公式来计算。
<arc:set attr="_map.lineItemCount" value= "[_map.lineItemCount | def(0) | add(1)]">
<arc:set attr="currentCost" value="[xpath(PricePerUnit) | multiply([xpath(Quantity)])]" />
<arc:set attr="currentTax" value="[currentCost | multiply([xpath(TaxPercent)]) | multiply(.01) | round(2)]" />
<arc:set attr="_map.totalCost" value="[_map.totalCost | def(0) | add([lineItemCost]) | add([lineItemTax])]" />
CTT01 元素可以直接映射到 _map.lineItemCount,因此打开脚本编辑器,直接引用前面的属性即可:
<arc:set attr="result.text">[_map.lineItemCount]</arc:set>
CTT02 元素可以直接映射到 _map.totalCost,然而 CTT 哈希需要忽略小数点,等于将费用乘以100:
<arc:set attr="result.text">[_map.lineItemCount | multiply(100)]</arc:set>
工作流总结
Database 端口从后端系统中生成采购订单数据,然后通过 X12 Map 端口将这个 XML 映射为 EDI 的 XML 格式。然后将 EDI XML 传给 X12 端口,添加交换头并将 XML 转换为 X12 格式。
工作流中最复杂的步骤是 XML 映射的建立。映射需要在父节点之间建立 Foreach 关系,然后使用拖拽操作映射单个 Leaf 节点,使用表达式编辑器,增加条件,编写自定义脚本。
示例数据
数据库输出映射
<Items>
<test_purchase_orders selectQuery="SELECT * FROM `test_purchase_orders` WHERE `Processed` = 0">
<PONumber key="true" />
<CurrencyCode />
<CustomerID />
<PODate type="datetime" />
<Processed type="int" updateValue="1" />
<RemitToAddr />
<RemitToCountry />
<RemitToID />
<RemitToState />
<RemitToZip />
<ShipToAddr />
<ShipToCountry />
<ShipToID />
<ShipToState />
<ShipToZip />
<Terms />
<test_po_line_items selectQuery="SELECT * FROM `test_po_line_items` WHERE `PONumber` = ${PONumber}">
<ItemID key="true" />
<PONumber />
<PricePerUnit type="double" />
<Quantity type="int" />
<TaxPercent type="double" />
</test_po_line_items>
</test_purchase_orders>
</Items>
X12 810
ISA*00* *00* *ZZ*VENDOR *ZZ*AMAZON *090322*1001*U*00400*000001631*0*T*>~
GS*IN*VENDOR*AMAZON*20090322*1001*480*X*004010~
ST*810*0001~
BIG*20090320*5002841638*20090311*Q6515853~
CUR*BT*CAD~
N1*RI*VENDORNAME~
N3*PO BOX 1234~
N4*TORONTO*ON*M5W 5M5*CA~
N1*ST*AMAZON CANADA~
N3*500 MCCARTHY DR*FAIRVIEW BUSINESS PARK~
N4*MISSISSAUGA*ON*L5R 3W5*CA~
ITD*01*3*****60~
IT1*1*4*EA*12.6*NT*UP*786932788990*VN*1012380100000*PO*Q2515852~
TXI*GS*2.52*5~
IT1*2*30*EA*29.5*NT*UP*786936725951*VN*1000570100000*PO*Q2515852~
TXI*GS*44.25*5~
IT1*3*90*EA*22.5*NT*UP*782936735321*VN*0543900100000*PO*Q2515852~
TXI*GS*101.25*5~
IT1*4*5*EA*29.5*NT*UP*786936782268*VN*1000570200000*PO*Q2515852~
TXI*GS*7.38*5~
TDS*326330~
TXI*GS*155.4*5*****3108*954090650~
CTT*4*129~
SE*22*0001~
GE*1*480~
IEA*1*000001631~