About Handlebar Helpers

You define metadata templates using helper functions which are based on Handlebar, a popular framework for templates.

Use the Handlebar helpers and application specific helper functions in the template for generating the metadata document. For each attribute in the JSON schema for the metadata, there is an associated helper function.

Using these helper functions significantly eases the creation of metadata templates as you don't need to know JSON syntax. This approach is backward compatible.

To define metadata document:

  • Enclose a metadata document within the following element.
    {{#metadataDocument}}
        ... {{/metadataDocument}}
  • You can use all native Handlebar helpers, such as {{#if}}, {{#each}}, {{#with}} for iterations and conditions.
  • Use utility helpers, such as concat, toTimestamp, etc. for string concatenation, data conversion, lookups, etc.
  • Each helper function that is associated with an attribute of the metadata's JSON schema, has the same name as the attribute and is prefixed by md:. For example, the helper function for the documentNumber attribute is md:documentNumber.
  • Use the metadata helper functions in any order.
  • You can use two types of helper functions:
    1. Use single-line helper functions for simple attributes that require a single value or for simple objects that don’t have nested objects. The helper functions can have position based parameters where the order of parameters is important or named parameters where the order is not important.
    2. Use block helper functions for complex attributes, such as object type attributes. A block helper function can contain single-line helpers or nested block helper functions within it. These helper functions have start (#) and end (/) modifiers.
  • You can associate the source document’s attribute with the document keyword.

Hierarchy of Helper Functions

The following image represents the hierarchical structure of using the helper functions in a metadata document.

Description of Document related helpers

This table describes the document helper functions used in to define metadata document:
Name Arguments Description Mandatory (Yes/No)
md:documentNumber Has a single parameter with a value To uniquely identify the document.

Example:

{{md:documentNumber document.OrderNumber}}
Yes
md:ledgerKey Has a single parameter with a value Unique value that acts as a key for a document in the distributed ledger.

Example:

{{md:ledgerKey (concat "purchase_order:"document.OrderNumber)}}
Yes
md:documentTypeId Has a single parameter with a value Determines the chronological order of a document in a trace. Document issue date, document creation date, and so on are typical attributes that may provide the value for this helper.

If this helper is not used in the template, then the value defaults to the time, the document was received by Oracle Intelligent Track and Trace. Number to identify the type of document.

Example:

{{md:documentTypeId "purchase_order"}}
Yes
md:documentTimestamp Has a single parameter with a value Transaction date whose value determines the chronological order of the document in a trace.

Example:

{{md:documentTimestamp (orDefault document.result.orderDate document.result.creationDate)}}
Yes
md:transactionValue Has a single parameter with a value Captures the value of the transaction, such as total order value or total invoice amount. Set it to zero if the document's value doesn't need to be tracked.

Example:

{{#md:transactionValue}} {{md:currencyCode (orDefault document.declaredValue.currencyCode "USD")}} {{md:amount (orDefault document.declaredValue.amount 0)}} {{/md:transactionValue}}
Yes
md:documentCrossRef DocumentNumber, DocumentTypeId, LedgerKey Contains zero or more references to other documents that have been recorded or will be recorded in the ledger. This vital value is used by the application to correlate transactions and business flows.

Example:

{{md:documentCrossRef documentNumber=document.result.vendorOrderNum documentTypeId="SalesOrder" ledgerKey=(concat "SalesOrder:" document.result.vendorOrderNum)}}
No
md:receiver tradingpartnerId and locationId Captures the trading partner Id of the intended receiver of the source document. This is typically used for documents that are part of B2B transactions, such as Purchase Order, Advanced Shipping Notice and so on.

Example:

{{md:receiver document.result.value.shipToPartyName by="name"}}
No
md:documentData Has a single parameter with a value. This helps to specify field names and their values. This helper is used to copy arbitrary data from the source document to the normalized documents.
Note: you need to define the type of data and the attribute names in the "Metadata Schema" for any other post processing.

Example:

{{md:documentData "billOfLadingNumber" document.result.value.billOfLadingNumber}}
No
#md:documentData md:documentData This is the block helper version of the md:documentData helper that enables capturing of attributes that are part of an object property defined in the Metadata Schema. No
md:reference Has a single parameter with a value Enables you to create a reference key if it has not been created in the system before or if a key with the same value already exists in the system then this document will be linked to that key.

Example:

Purchase Order document {{#metadataDocument}} {{md:documentNumber document.OrderNumber}} {{md:ledgerKey (concat "PurchaseOrder:" document.OrderNumber)}}

Sales Order document {{#metadataDocument}} {{md:documentNumber document.OrderNumber}} {{md:ledgerKey (concat "SalesOrder:" document.OrderNumber)}} {{md:documentCrossRef ledgerKey=(concat "PurchaseOrder:" document.CustomerPONumber)}} {{md:reference document.CustomerPONumber}}

Delivery document Delivery (TransactionId, deliveryDate)   {{ledgerKey = "delivery:TransactionId"}}   {{md:reference document.TransactionId)}}

Here, the Purchase Order and Sales Order documents are correlated based on md:documentCrossRef value that exactly matches the ledger key value.

The Delivery document does not have data to link with Purchase Order or Sales Order document using ledger key. So, the correlation is formed using the reference key when the reference key attribute value (document.CustomerPONumber) of the Sales Order document in a business flow matches with the reference key attribute value (document.TransactionId) of the Delivery document.

No

Tracking Data (IoT) Related Helpers

These helper functions are used to represent IoT related data of items, such as the geographic location, temperature, pressure, or vibration, which are obtained from various sensor attributes linked to the items or packages..

  • #md:trackingData
  • md:geolocation
  • #md:metric

Description of Tracking Data (IoT) related helpers

This table describes the Tracking Data (IoT) related helper functions used in to define metadata document:
Name Arguments Description Mandatory (Yes/No)
md:trackingdata

An object with several nested objects as seen in this structure

{{#md:trackingData}} {{md:timestamp 0}} {{md:geoLocation lat=0 lon=0 alt=0}} {{#md:metric}} {{md:name ""}} {{md:label ""}} {{md:quantity unitCode="" value=0}} {{/md:metric}} {{/md:trackingData}}

Used for tracking IoT data. If trackingData is used, geoLocation must be specified. The metrics array is a list of different measurements, such as pressure, temperature, vibration, and so on, recorded at the current point in time and at current location.

Example:

{{#md:trackingData}} {{md:timestamp (toTimestamp document.EventData.Timestamp)}} {{#md:geoLocation}} {{md:lat document.EventData.GeoLocation.lat}} {{md:lon document.EventData.GeoLocation.lon}} {{md:alt document.EventData.GeoLocation.alt}} {{/md:geoLocation}} {{#each document.EventData.SensorValues as |item|}} {{#md:metric}} {{md:name item.Name}} {{md:label item.Name}} {{#md:quantity}} {{md:unitCode item.Value.unitCode}} {{md:value item.Value.value}} {{/md:quantity}} {{/md:metric}} {{/each}} {{/md:trackingData}}
No

Item Tracking Related Helpers

These helper functions are used to capture item tracking, package tracking, or batch tracking data.

Description of Item Tracking related helpers

This table describes the Item Tracking related helper functions used in to define metadata document:

Name Arguments Description Mandatory (Y/N)
md:itemTrackingData No arguments but either of these qualifiers: lotControlled, serialControlled, unassignedControlled The content of this item tracking block helper function depends on the qualifier used in this block. View a typical structure in Sample Structures of Item Tracking Metadata Helper Functions. No
md:packageTrackingData packageControlled This helper is used to capture packaging related information present in the source document. View typical structures in Sample Structures of Item Tracking Metadata Helper Functions. No
md:batchTrackingData batchControlled This helper is used to capture batch or (parent lot) data available in the source document. A batch is either a collection of lots or collection of serial numbers. View typical structures in Sample Structures of Item Tracking Metadata Helper Functions. No
md:itemTypeId a single value that is typically retrieved by using a nested helper mapItemType Declares the ID of the item type that needs to be tracked. An item referenced in a document needs to mapped to the appropriate item type registered in the application. This mapping is done by the look-up helper function mapItemType.

Example:

{{md:itemTypeId (mapItemType item.itemNumber (lookupSubmitter))}}
Yes
md:itemEventType Values from: CREATED, USING, ORDERED, RECEIVED, SHIPPED, MOVED, RETURNED This line helper function defines the value of the event type.

Example:

{{md:itemEventType "SHIPPED"}}
Yes
md:description A string value that describes the item. This line helper function defines the description of the item.

Example:

{{md:description item.itemDescription}}
No
md:serialNumber A single value This line helper function is used with serial-controlled item tracking data.

Example:

{{md:serialNumber itemSerial.fromSerialNumber}}
Yes
md:currentCustody A single value Defines the details of the organization that currently has custody of the item.

Example:

{{#md:currentCustody}} {{md:custodyChangeReason "UNASSIGNED | TRANSFERRED | SOLD | RETURNED | SHIPPED"}} {{#md:tradingPartner}} {{md:tradingPartnerId ""}} {{/md:tradingPartner}} {{#md:tradingPartner}} {{md:tradingPartnerName ""}} {{/md:tradingPartner}} {{#md:location}} {{md:locationId ""}} {{/md:location}} {{#md:location}} {{md:locationAddress ""}} {{/md:location}} {{/md:currentCustody}}
Yes
md:custodyChangeReason A single value Defines the reason for which the custody of the item changed.

Example:

{{md:custodyChangeReason "UNASSIGNED | TRANSFERRED | SOLD | RETURNED | SHIPPED"}}
Yes
md:tradingPartner A single value Defines the details of the trading partner that has custody of the item.

Example:

{{#md:tradingPartner}} {{md:tradingPartnerId ""}} {{/md:tradingPartner}}
No
md:tradingPartnerId A single value It is used if the trading partner is part of the network. The trading partner ID can be looked up using the trading partner's name or an ID using either lookupSubmitter, lookupReceiver, or lookupTradingPartner utility helpers as appropriate.

In addition to look-up the trading partner ID, the output parameter in the lookupSubmitter and lookupTradingPartner helpers also returns other attributes, such as trading partner address along with its longitude, and latitude details in JSON format or only the trading partner ID.

Example

{{md:location locationId=(lookupTradingPartner "DC-ID" document.ShipToOrganizationCode by="location" output="locId" whenMissing="fail") "id": "12", "tradingPartnerId": "12", "locationId": "44",locations "id": "12", "name": "Delta Glass", "address": "Phoenix, E Euclid Ave, AZ, 85042, US", "coordinates": { "latitude": 47.98889, "longitude": 8.79116 }}}
Yes
md:tradingPartnerName A single value It is used if the trading partner that has custody of the item is not part of the Oracle Intelligent Track and Trace network.

Example, see md:currentCustody

Yes
md:location A single value Defines the location for trading partner that is part of the network who has custody. The location details can be looked up using the lookupTradingPartner utility helper function.

Example, see md:currentCustody

No
md:locationAddress A single value This is used for a trading partner that is not part of the network and defines the address of the location of the trading partner that has custody.

Example, see md:currentCustody

Yes
md:lotNumber A single value This identifies the unique lot number of the items.

Example:

{{md:lotNumber item.lotNumber}}
Yes
md:quantity A single value This block helper function has two line helper functions, md:unitCode and md:value.

Example:

{{#md:quantity}} {{md:unitCode (orDefault item.shippedQuantity.unitCode "Ea")}} {{md:value (orDefault item.shippedQuantity.value 0)}} {{/md:quantity}}
No
md:unitCode A single value This line helper function is used underneath md:quantity.

Example:

{{md:unitCode (orDefault item.shippedQuantity.unitCode "Ea")}}
Yes
md:value A single value This line helper function is used underneath md:quantity.

Example:

{{md:value (orDefault item.shippedQuantity.value 0)}}
Yes
md:comments A string value This line helper function is used for providing additional information as comments. No
md:serialEventType A single value This helper is used to capture serialization events, such as "COMMISSION", "DECOMISSION" and so on. Yes
mapItemType Have two arguments. The first parameter is a string value representing the item code. The second parameter is a string value of the internal id of the trading partner, which typically retrieved by using another helper function. This helper function is used to lookup the internal ID for the item type referenced in the source document. An item type can be looked up either in the master catalog (founder's item types list) or in the submitting trading partner's list. Based on where you need to lookup, use lookupFounder or lookupSubmitter appropriately.

Examples:

{{mapItemType ItemTypeCode=shipmentLine.ItemNumber tpId=(lookupFounder)}}

{{mapItemType ItemTypeCode=shipmentLine.ItemNumber tpId=(lookupSubmitter) )}}

{{mapItemType ItemTypeCode-shipmentLine.ItemNumber "something"}}

If the item type code is not found in the submitting trading partner's list, the whenMissing parameter allows the helper to use item type code from the founder's list.

Example:

{{mapItemType ItemTypeCode=shipmentLine.ItemNumber tpId=(lookupSubmitter) whenMissing='ignore' {{mapItemType ItemTypeCode=shipmentLine.ItemNumber tpId=(lookupFounder)}}

Yes
md:packageTypeId A single parameter string value that is retrieved from another helper mapPackageType.. This nested helper function represents an internal id of the package type that is retrieved from another helper mapPackageType.

Example:

{{md:packageTypeId (mapPackageType "box")}}
Yes
mapPackageType A single parameter with a value.

This line helper function returns a string that represents the internal id of a package type and it accepts the name of the package type created by a founder.

Example:

{{mapPackageType PackageType=packingUnit.PackingType}}
yes
md:packageEventType a value from: PACKED, STORED, SHIPPED Defines if a package is packed, waiting to be shipped, or received and stored.

Example:

{{md:packageEventType "SHIPPED"}}
No
md:referencedItem Depends on the context of its usage This helper allows capture of parent/child relationships of items. It should be used to capture ingredient or component usage to produce or manufacture semi-finished or finished products.

Example:

{{#md:referencedItem:lotControlled}} {{md:itemTypeId (mapItemType shipmentLine.Item (lookupFounder))}} {{md:lotNumber shipmentLine.LotNumber}} {{md:quantity (orDefault shipmentLine.RequestedQuantityUOMCode "EA") (orDefault shipmentLine.ShippedQuantity 0)}} {{/md:referencedItem:lotControlled}}
No. For batch controlled metadata, it is mandatory.

Common Utility Helpers

  • jsonItem
  • toTimestamp
  • Sum
  • Find
  • split
  • regexpFind
  • String helpers
  • Condition helpers

Description of Common Utility related helpers

This table describes the Tracking Data (IoT) related helper functions used in to define metadata document:
Name Arguments Description Mandatory (Yes/No)
jsonItem Has a single parameter with a value Prints json without quotes. For more information, see https://github.com/jknack/handlebars.java#jackson-2x No
toTimestamp Has a single parameter with a value

Converts date/time-formatted string to timestamp number.

Supported hash parameters
  • format - String format as defined in java.time.format.DateTimeFormatter or ISO instant, if not defined.
  • zone - timezone if required by format or GMT, if not defined.
  • locale - locale if required by format or root locale, if not defined.
No
sum Has multiple parameters with values

Sum all arguments in the format

{{sum a.value b.value c.value}}

No
find Has a single parameter with a value Finds an element with the property set to a particular value. No
split Have single or multiple parameters Extract a sub-string from a given text by specifying a separator.

Supported parameters

  • text (required) - text value to be split into segments.
  • delimiter (optional) - the delimiting regular expression (regexp). Default value is '\s+'.
  • index (optional) - a negative or a non-negative integer specifying the position of a segment. Negative values starts from the end of the string and positive values from the start of the string. For example, -1 is last and -2 is one before the last and so on.
    Note: If index is missing, entire array is returned.
  • whenMissing (optional) - Specifies the behavior when index or delimiter is incorrect. The default value is 'fail'.
See Examples of Utility Helper Functions
No
regexpFind Have single or multiple parameters Extract a single or multiple occurrences of a sub-string from a given text that matches the regular expression.

Supported parameters

  • text (required) - text value to be split into segments.
  • pattern (required) - the regular expression pattern.
  • index (optional) - a negative or a non-negative integer specifying the position of a segment. Negative values starts from the end of the string and positive values from the start of the string. For example, -1 is last and -2 is one before the last and so on.
    Note: If index is missing, entire array is returned.
  • group (optional) - an integer or string value capturing the group index/name. In case group is a string value, it specifies the name of the named capturing group.
  • whenMissing (optional) - Specifies the behavior when index or delimiter is incorrect. The default value is 'fail'.
See Examples of Utility Helper Functions
No
String helpers Have single or multiple parameters String helper functions publicly available at https://github.com/jknack/handlebars.java#string-helpers No
Conditional helpers Have single or multiple parameters Conditional helper function publicly available at https://github.com/jknack/handlebars.java#conditional-helpers No

Common Helpers

These helper functions are used across all helpers including item tracking helper functions, as sub helpers.
  • md:name
  • md:label
  • #md:quantity
  • md:unitCode
  • md:value
  • md:comments

Description of Common Helpers

This table describes the Common helper functions used in to define metadata document:
Name Arguments Description Mandatory (Yes/No)
md:quantity A single value This block helper function has two line helper functions, md:unitCode and md:value.

Example:

{{#md:quantity}} {{md:unitCode (orDefault item.shippedQuantity.unitCode "Ea")}} {{md:value (orDefault item.shippedQuantity.value 0)}} {{/md:quantity}}
No
md:unitCode A single value This line helper function is used underneath md:quantity.

Example:

{{md:unitCode (orDefault item.shippedQuantity.unitCode "Ea")}}
Yes
md:value A single value This line helper function is used underneath md:quantity.

Example:

{{md:value (orDefault item.shippedQuantity.value 0)}}
Yes
md:comments A string value This line helper function is used for providing additional information as comments. No
md:name A string value This line helper function is used underneath md:trackingData No
md:label A string value This line helper function is used underneath md:trackingData No

Single-Line Helper Functions

Description of Single-Line Helpers

This table describes the Tracking Data (IoT) related helper functions used in to define metadata document:
Name Arguments Description Mandatory(Yes/No)
md:documentNumber Has a single parameter with a value Number to identify the document.

Example:

{{md:documentNumber document.OrderNumber}}
Yes
md:DocumentTypeId Has a single parameter with a value Number to identify the type of document.

Example:

{{md:documentTypeId "purchase_order"}}
Yes
md:ledgerKey Has a single parameter with a value Unique value that acts as a key for a document in the distributed ledger.

Example:

{{md:ledgerKey (concat "purchase_order:"document.OrderNumber)}}
Yes
md:documentCrossRef DocumentNumber,DocumentTypeId,LedgerKey Contains zero or more references to other documents that have been recorded or will be recorded in the ledger. This vital value is used by the application to correlate transactions and business flows.

Example of position based parameters

{{md:documentCrossRef document.SupplierOrderNumber (concat "sales_order:"document.SupplierOrderNumber) "sales_order"}}

Example of named parameters

{{md:documentCrossRef documentNumber=document.SupplierOrderNumber documentTypeId=(concat "sales_order:"document.SupplierOrderNumber) ledgerKey="sales_order"}}
No
Note: For the descriptions of the helper functions, review the following table and for their examples, view Usage Examples

Examples of Block Helper Functions

A block helper function with single-line helpers
{{#md:documentCrossRef}}    
            {{md:documentNumber document.SupplierOrderNumber}}
            {{md:documentTypeId (concat "sales_order:"document.SupplierOrderNumber)}}    
            {{md:ledgerKey "sales_order")}}
{{/md:documentCorssRef}}

A nested block helper function

{{#md:itemTrackingData:lotControlled}}
                {{md:itemTypeId  (mapItemType itemTypeCode=document.ProductCode tpId=(lookupFounder))}}
                {{md:lotNumber  document.LotNumber}}
                {{#md:quantity}}
                    {{md:unitCode  document.UnitCode}}
                    {{md:value  document.Quantity}}
                {{/md:quantity}}
                {{md:itemEventType  “CREATED”}}
                {{#each document.ReceivedLots as |receivedLot|}}
                    {{#md:referencedItem:lotControlled}}
                        {{md:itemTypeId  (mapItemType itemTypeCode=receivedLot.ProductCode tpId=(lookupFounder))}}
                        {{md:lotNumber  receivedLot.LotNumber}}
                        {{md:quantity  unitCode=receivedLot.UnitCode value=(orDefault receivedLot.Quantity 0)}}
                    {{/md:referencedItem:lotControlled}}
                {{/each}}
                {{#md:attributes}}
                    {{md:classification document.ClassificationCode}}
                {{/md:attributes}}
            {{/md:itemTrackingData:lotControlled}}

Examples of Utility Helper Functions

sum helper function

Example
##Example JSON: 
        {   
            “Attr1”: “some value”,    
            “Qty1": 10,
            “Qty2”: 200,
             “anArray”: [                       
              {                       
                 “name”: “Temperature”,                       
                 “value”: 40                       
              },                       
              {                       
                 “name”: “Pressure”,                       
                 “value": 14                        
              },                       
              {                       
                “name”: “Humidity”,                    
                “value”: 45 
              }]
        } 
##Example of sum and  find:    
        {            
            “total”: {{sum document.Qty1 document.Qt2}},            
            {{find document.anArray “name” “Pressure" as |reading| }}
            “pressureReading”:reading.value        
            {{/find}}
        } 
##Example Result:
        {            
            “total”: 120,            
            “pressureReading”: 14
        } 

find helper function

Example
{{#find some.array "x" "yy" as |o i| }}{{o.n }} {{i}} {{@key}} {{@index}} 
{{else}}na{{/find}}

Find object in an array (or object) with field "x": "yy". Inside the block, o is referencing the object found, i is the index of the object. Both can be named differently. Also, special keys are available inside the block, with self-explanatory names: @key, @index, where key has the same value as index in arrays. It is modeled in the similar fashion as handlebars "each" helper, including the "else" block. Most of these parameters are optional, the minimal find helper is {{find arr "x" "yy"}} prints the object with "x":"yy" field.

The split helper function uses the following syntax:


{{split text delimiter=<regex> index=<index> whenMissing=<fail|ignore>}}

{{split 'a b'}}                                                                     // resolved as  '[a, b]'
{{split 'a b' index=0}}                                                             // resolved as  'a'
{{split 'a b' index=1}}                                                            // resolved as  'b'
{{split 'a b' index=-1}}                                                           // resolved as  'b'
{{split '/shipment/shipmentID' delimiter='/' index=3 whenMissing='fail'}}          // fails with error: Invalid index parameter: '3'
{{split '/shipment/shipmentID' delimiter='/' index=3 whenMissing='ignore'}}        // resolved as '' (empty string)

Example

## Sample Document

{   
    "Name" : {
        "firstName" : "Testabcd",
        "lastName" : "Helperefgh"
    },
    "uri": "shipment/shipmentId",
    "BillOfLadingNumber": "80000000099",
    "CarrierName": "Zeta Carrier",
    "Consignment": [
        {
            "PONumber": "GHPO-21029000123",
            "LPN": "ZXR40034501",
            "ContainerType": "CONTAINER-8",
            "PackageCount": 1,
            "Weight": {
                "unitCode": "KG",
                "value": 980
            }
        }
    ],

In the document schema, uri is set to "uri": "/shipment/shipmentId" and you want to extract the last sub-string of the uri text.

In a metadata document, the split helper function helps you extract a sub-string from the given text.
{{md:documentData "uri-last" (split document.uri delimiter='/' index=-1 whenMissing='ignore' )}}

    {{#each document.Consignment as |consignment|}}
        {{#md:packageTrackingData}}
            {{md:controlType  "PACKAGE_CONTROLLED"}}
            {{md:packageNumber  consignment.LPN}}
            {{md:packageTypeId  (mapPackageType consignment.ContainerType)}}
            {{md:packageEventType  "SHIPPED"}}
        {{/md:packageTrackingData}}
    {{/each}}

As a result, the following data processed by the metadata template:
"documentData": {
  "uriLast": "shipmentId"
}
regexpFind helper function uses the following syntax:

{{regexpFind  text  pattern  index=<index>  group=<groupIndex or groupName> whenMissing=<fail|ignore>}}

{{regexpFind '/a1/b2/C3/d4' '[a-z0-9]+'}}                              // result: [a1, b2, 3, d4] (all segments matching the pattern)
{{regexpFind '/a1/b2/C3/d4' '[a-z0-9]+' index=0}}                                // result: 'a1' (first segment matching the pattern)
{{regexpFind '/a1/b2/C3/d4' '[a-z0-9]+' index=-1}}                               // result: 'd4' (last segment matching the pattern)
{{regexpFind '/a1/b2/C3/d4' '[a-z0-9]+' index=2}}                                // result: '3' (third segment matching the pattern)
{{regexpFind '/a1/b2/C3/d4' '(?i)[a-z0-9]+' index=2}}                            // result: 'C3' (case insensitive pattern is used)
{{regexpFind '/a1/b2/C3/d4' '[a-z0-9]+' index=-1 group=0}}                       // result: 'd4' (last segment matching the pattern)
{{regexpFind '/a1/b2/C3/d4' '[a-z0-9]+' index=-1 group=1}}                       // fails with error: Invalid group parameter: '1'
{{regexpFind '/a1/b2/C3/d4' '[a-z0-9]+' index=-1 group=1 whenMissing='ignore'}}  // result: '' (empty string)
For example, you can use regexpFind helper function to extract the firstname and the lastname from "Name".
#with (regexpFind document.Name.firstName '[a-zA-Z][a-z]?') as |segments|
md:documentData "nickName" (concat segments.0 segments.1)"
md:documentData "nickName2" (concat segments.0 ' ')"
md:documentData "nickName3" (concat segments.1 ' ')"
md:documentData "nickName4" (concat segments.2 ' ')"
md:documentData "nickName5" (concat segments.3 ' ')"

/with

As a result, the following data processed by the metadata template:

"Name" :

{ "firstName" : "Testabcd", "lastName" : "Helperefgh" }

Usage Example

Let us take a metadata document sample of a Shipping document type that is used to inspect quality report of the shipped goods. The important attributes captured are:

  • documentCrossRefs—Refers to other documents WorkOrder and ReceivingReceipt
  • documentData—Defines additional attributes which must be captured during document ingestion.
{#metadataDocument}}
    {{md:documentNumber document.IpEventId}}
    {{md:ledgerKey (concat "QAInspection:" document.IpEventId)}}
    {{#if document.WorkOrderId}}
        {{md:documentCrossRef documentNumber=document.WorkOrderId documentTypeId="WorkOrder"
                              ledgerKey=(concat "WorkOrder:" document.WorkOrderId)}}
    {{/if}}
    {{#if document.DocNumber}}
        {{md:documentCrossRef documentNumber=document.DocNumber documentTypeId="ReceivingReceipt"
                              ledgerKey=(concat "ReceivingReceipt:" document.DocNumber)}}
    {{/if}}
    
    {{md:transactionValue "USD" 0}}
    {{md:documentData "InspectionType" document.EventType}}
    {{md:documentData "SamplingQty" document.SamplingQty}}
    {{md:documentData "QtyInspected" document.QtyInspected}}
    {{md:documentData "QtyReject" document.QtyReject}}
    {{md:documentData "InspectionDate" document.InspectionDate}}
{{/metadataDocument}}

For a submitted Shipping document, the following is the generated metadata JSON schema:

{
    "documentTypeId": "shipping",
    "documentVariantId": "demo_asn",
    "ledgerKey": "shipping:DMSN-113512",
    "documentNumber": "DMSN-113512",
    "originalDocumentRef": {
        "location": {
            "bucket": "requests_ascus_test",
            "object": "39_43_d0ba0327-0f95-4896-8e2d-af2d62c73d2e/document"
        },
        "documentHash": "81b7c39fcee7302868c2771fe029b3beb70fb4f47bb27e0188795c08688ead7f736ccf994f83b05a5a2cb0e6b70a5430a8a77e196522f0f65f5ae42a011af96c"
    },
    "requestBodyRef": {
        "location": {
            "bucket": "requests_ascus_test",
            "object": "39_43_d0ba0327-0f95-4896-8e2d-af2d62c73d2e/document"
        },
        "documentHash": "81b7c39fcee7302868c2771fe029b3beb70fb4f47bb27e0188795c08688ead7f736ccf994f83b05a5a2cb0e6b70a5430a8a77e196522f0f65f5ae42a011af96c"
    },
    "attachmentsRefs": [],
    "receivedTimestamp": 1639390270482,
    "documentTimestamp": 1620436086047,
    "submitter": {
        "tradingPartnerId": "21"
    },
    "receiver": {
        "tradingPartnerId": "29",
        "locationId": "32"
    },
    "itemTrackingData": [
        {
            "itemTypeId": "Eftw5QPDFrBVgaxxH1B7Rw",
            "lotNumber": "OAT-4001-1231",
            "quantity": {
                "unitCode": "KG",
                "value": 400,
                "normalized": {
                    "unitCode": "kg",
                    "value": 400,
                    "class": "MASS"
                }
            },
            "itemEventType": "SHIPPED",
            "controlType": "LOT_CONTROLLED"
        }
    ],
    "packageTrackingData": [
        {
            "controlType": "PACKAGE_CONTROLLED",
            "packageNumber": "DM-P-3512-4001",
            "packageTypeId": "predefined_package",
            "packageEventType": "SHIPPED",
            "referencedItems": [
                {
                    "itemTypeId": "Eftw5QPDFrBVgaxxH1B7Rw",
                    "lotNumber": "OAT-4001-1231",
                    "quantity": {
                        "unitCode": "KG",
                        "value": 400,
                        "normalized": {
                            "unitCode": "kg",
                            "value": 400,
                            "class": "MASS"
                        }
                    },
                    "controlType": "LOT_CONTROLLED"
                }
            ]
        },
        {
            "controlType": "PACKAGE_CONTROLLED",
            "packageNumber": "DM-P-3512-4000",
            "packageTypeId": "predefined_pallet",
            "packageEventType": "SHIPPED",
            "referencedItems": [
                {
                    "packageTypeId": "predefined_package",
                    "packageNumber": "DM-P-3512-4001",
                    "controlType": "PACKAGE_CONTROLLED"
                }
            ]
        }
    ],
    "transactionValue": {
        "currencyCode": "USD",
        "amount": 0
    },
    "documentData": {},
    "documentCrossRefs": [
        {
            "documentNumber": "DMSO-32512",
            "ledgerKey": "sales_order:DMSO-32512",
            "documentTypeId": "sales_order"
        },
        {
            "documentNumber": "NFPO-71512",
            "ledgerKey": "purchase_order:NFPO-71512",
            "documentTypeId": "purchase_order"
        }
    ]
}

Item Tracking Metadata Document Example

This example is a metadata document of Work process product completion document type and represents lot controlled and serial controlled item tracking data.
{{#metadataDocument}}
    {{md:documentNumber document.TransactionId}}
    {{md:ledgerKey (concat "WorkProcessProductCompletion:" document.TransactionId)}}
    {{#if document.SourceReference}}
        {{md:documentCrossRef documentNumber=document.SourceReference documentTypeId="process_work_order"
                              ledgerKey=(concat "ProcessWorkOrder:" document.SourceReference)}}
    {{/if}}
    {{md:documentTimestamp (toTimestamp document.TransactionDate)}}
    {{#each document.lots as |item|}}
        {{#md:itemTrackingData:lotControlled}}
            {{md:itemTypeId (mapItemType document.Item (lookupFounder)) whenMissing='ignore'}}
            {{md:description document.ItemDescription}}
            {{md:lotNumber item.LotNumber}}
            {{#md:quantity}}
                    {{md:unitCode (orDefault document.TransactionUOMCode "Ea")}}
                    {{md:value (orDefault item.TransactionQuantity 0)}}
                {{/md:quantity}}
            {{md:itemEventType "CREATED"}}
        {{/md:itemTrackingData:lotControlled}}
    {{/each}}
    {{#each document.serials as |item|}}
        {{#md:itemTrackingData:serialControlled}}
            {{md:itemTypeId (mapItemType document.Item (lookupSubmitter)) whenMissing='ignore' 
            {{mapItemType ItemTypeCode=shipmentLine.ItemNumber tpId=(lookupFounder)}}
            {{md:description document.ItemDescription}}
            {{md:serialNumber item.SerialNumber}}
            {{md:serialEventType "COMMISSIONED"}}
            {{md:itemEventType "CREATED"}}
        {{/md:itemTrackingData:serialControlled}}
    {{/each}}
    {{md:transactionValue "USD" 0}}
    {{md:documentData "TransactionSourceType" document.TransactionSourceType}}
    {{md:documentData "TransactionAction" document.TransactionAction}}
{{/metadataDocument}}

The following is an example of the generated metadata JSON schema for a submitted Work process product completion document.

{
    "documentTypeId": "work_process_product_completion",
    "ledgerKey": "WorkProcessProductCompletion:90002001801",
    "documentNumber": "90002001801",
    "originalDocumentRef": {
        "location": {
            "bucket": "documents_demovac1_test",
            "object": "42_45_d5d68001-b426-491e-a3a0-6a463bd375d5/document"
        },
        "documentHash": "6b34d8d9e26ef5a6cd8ea7ec8f145743f69ac1dee284306c87f77c11673536f0460379c8cf2ed93f5d347c8c1cfcfae39ae1e58102b22ece2498abef2df3eebe"
    },
    "attachmentsRefs": [],
    "receivedTimestamp": 1616613435457,
    "documentTimestamp": 1608804600000,
    "submitter": {
        "tradingPartnerId": "98"
    },
    "receiver": {
        "tradingPartnerId": "98"
    },
    "itemTrackingData": [
        {
            "itemTypeId": "63gCmnAXAGoKCSWtyppx2K",
            "description": "10-Dose Flu Vaccine",
            "lotNumber": "FL-VAC-20210106-12012",
            "quantity": {
                "unitCode": "EA",
                "value": 3000
            },
            "itemEventType": "CREATED",
            "controlType": "LOT_CONTROLLED"
        }
    ],
    "transactionValue": {
        "currencyCode": "USD",
        "amount": 0
    },
    "documentData": {
        "TransactionSourceType": "PROCESS WORK ORDER",
        "TransactionAction": "WORK ORDER COMPLETION"
    },
    "documentCrossRefs": [
        {
            "documentNumber": "WO-3400122",
            "documentTypeId": "process_work_order",
            "ledgerKey": "ProcessWorkOrder:WO-3400122"
        }
    ]
}

Metadata Document Generation Process

The metadata template is used by the application to generate a normalized document from the incoming document at runtime. This normalized document is the one that is used for processing information written to the blockchain platform.