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 thedocumentNumber
attribute ismd:documentNumber
. - Use the metadata helper functions in any order.
- You can use two types of helper functions:
- 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.
- 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.
![](images/hierarchy_helper_func.gif)
Description of Document related helpers
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 Sales Order document Delivery document Here,
the Purchase Order and Sales Order documents are correlated
based on 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
|
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
Name | Arguments | Description | Mandatory (Yes/No) |
---|---|---|---|
md:trackingdata
|
An object with several nested objects as seen in this structure
|
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 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:
If the item type
code is not found in the submitting trading partner's list, the
Example:
|
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
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
|
No |
sum
|
Has multiple parameters with values |
Sum all arguments in the format
|
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
|
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
|
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
-
md:name
-
md:label
-
#md:quantity
-
md:unitCode
-
md:value
-
md:comments
Description of Common Helpers
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
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 |
Examples of Block Helper Functions
{{#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 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
{{#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.
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}}
"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)
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
{{#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.