Let’s say you’re responsible for producing retail or service invoices for some company that has outlets all over the country. Every province and/or state has their own unique tax laws and your invoices need to accommodate the appropriate ones.
Sample Invoice for British Columbia Sample Invoice for Newfoundland
Wouldn’t it be nice if your automated process could automatically drop in the right tax fields, complete with calculations, based on the province/state field of each record in the massive xml data file?
This sample demonstrates a new feature in LiveCycle ES2 – the ability to dynamically assemble an XDP template within a running process. It also demonstrates how to break up that massive xml data file and iterate through the records one at a time. While the LiveCycle Output service manages iterative loading intuitively, attempting a similar scenario with Assembler has unfortunately always been rather more, uh, challenging.
Dynamic Assembly is managed with what are called “insertion points” in the XDP file. If you open the SalesInvoice.xdp file in Designer, you’ll note that the Body.Total.Taxes subform has been defined as an insertion point.
This subform will be overwritten by one of the fragments contained in the TaxFrags.xdp file. How does the process know which fragment to throw in there, you ask? Well, the process gets the value of the province field from the data and feeds it to the Assembler Service. The magic happens in the DDX file, which looks like this:
<!– Assemble unique tax fragment from library –>
<XDPContent insertionPoint=”TaxFields” source=”application:///InvoiceSample/1.0/Forms/Fragments/taxfrags.xdp” fragment=”inputmap:///province”/>
The fragment attribute in XDPContent maps to the value stored in the process variable. Give it a shot. Import the sample LCA file into your ES2 server. It will create an application called InvoiceSample. Open the AssembleInvoices process in Workbench. The annotation explains how to run the sample.
As I mentioned earlier, this sample also demonstrates how to break up the incoming xml file and iterate through the records. Since the XDP is bound to a schema, the individual data nodes need to match the schema in order for the data to show up in the rendered PDF. After using XPath to extract a single node, that node then needs to be re-wrapped in the original root element in order to again match the schema. This work is done in the “Extract single data record” operation of the process. The node is first serialized, then a concat() function is used to wrap string versions of the element at the front and back, and is finally deserialized. If anyone know a better/simpler way to do this, I’m all ears.