Document Templates
Socotra’s document rendering engine uses templates written in a language called Liquid, created by Shopify. For more information see the Liquid Language Reference.
Socotra supports a set of custom functions in Liquid, documented here: Socotra Liquid Filters
Templates have names of the form *.template.liquid
, and are a combination of HTML and liquid markup that accesses and processes policy data.
Data Available in Templates
All policy information is available in a structure called data.policy
. For example, gross premium for the first segment of a policy can be referenced in a document template as data.policy.characteristics[0].gross_premium
.
The object hierarchy for data available to the document template is:
{
"data": {
"policy": {
"characteristics": [{
"tax_groups": [{}]
}],
"exposures": [{
"characteristics": [{}],
"perils": [{
"characteristics": [{}]
}]
}],
"modifications": [{
"exposure_modifications": [{
"peril_modifications": [{}]
}]
}],
"invoices": [{
"statuses": [{}],
"payments": [{}]
}],
"fees": [{}]
},
"policyholder": {
"entity": {}
}
}
}
Note
See Endorsement Documents and Renewal Documents for data available in templates during Endorsements and Renewals.
Note
When rendering numerical field values, generally you will want to use a filter for formatting; otherwise numbers will be rendered in exponential format. For example, instead of including the expression {{ data.policy.characteristics[0].field_values.annual_miles }}
, instead use {{ data.policy.characteristics[0].field_values.annual_miles | format_number_pattern: "0" }}
Details of the data Object
ValuesMaps
Many objects below refer to a “ValuesMap”, which is an implementation of a multimap data structure. A ValuesMap contains key-value pairs where the value can be a single value or an array, depending on whether that field was configured to be repeatable. The ValuesMap for field values is structured like this:
{
"field1": "value1",
"field2": ["value2", "value3"]
}
Note
This map is different from the data structures in the API, where all map data structures are key/array pairs.
Field Groups
In the field_values
objects below, the value for fields of the group type is an array of locators. The groups of fields themselves are in an object called field_groups_by_locator
. That object contains all field groups, not just those for the field in question. Use this example implementation as a starting point. This outputs the accessory_type field from each “accessory” field group:
{% assign exposure_values = data.exposure_characteristics.field_values %}
{% assign exposure_groups = data.exposure_characteristics.field_groups_by_locator %}
{% for accessory_loc in exposure_values.accessory %}
{% assign accessory = exposure_groups[accessory_loc] %}
{{accessory.accessory_type}}
{% endfor %}
data.policy
Details of the policy’s child objects are in the following sections.
{
"locator": string,
"policyholder_locator": string,
"product_locator": string,
"display_id": string,
"quote_locator": string,
"quote_name": string,
"created_timestamp": long,
"updated_timestamp": long,
"issued_timestamp": long,
"gross_fees": number,
"gross_fees_currency": string,
"characteristics": [{}],
"exposures": [{}],
"modifications": [{}],
"invoices": [{}],
"fees": [{}],
"commissions": [{}],
"cancellation": {
"modification_locator": string,
"modification_name": string,
"effective_timestamp": long
},
"payment_schedule_name": string,
"original_contract_start_timestamp": string,
"original_contract_end_timestamp": string,
"effective_contract_end_timestamp": string
}
data.policyholder
{
"locator": string,
"id": string,
"created_timestamp": long,
"updated_timestamp": long,
"entity": {
"accountLocator": string,
"entityType": string,
"values": ValuesMap,
"subValuesByLocator": map<String, ValuesMap>,
"createdTimestamp": long,
"updatedTimestamp": long
}
}
data.policy Child Objects
data.policy.characteristics
[
{
"locator": string,
"policyholder_locator": string,
"product_locator": string,
"start_timestamp": long,
"end_timestamp": long,
"gross_premium": number,
"gross_premium_currency": string,
"gross_taxes": string,
"gross_taxes_currency": string,
"issued_timestamp": long,
"field_values": ValuesMap,
"field_groups_by_locator": map<String, ValuesMap>,
"created_timestamp": long,
"updated_timestamp": long,
"tax_groups": [
{
"name": string,
"amount": number,
"amount_currency": string
}
]
}
]
data.policy.exposures
[
{
"locator": string,
"name": string,
"display_id": string,
"characteristics": [
{
"locator": string,
"policy_locator": string,
"policyholder_locator": string,
"product_locator": string,
"start_timestamp": long,
"end_timestamp": long,
"created_timestamp": long,
"updated_timestamp": long,
"field_values": ValuesMap,
"field_groups_by_locator": map<String, ValuesMap>
}
],
"perils": [
{
"locator": string,
"display_id": string,
"name": string,
"characteristics": [
{
"locator": string,
"issued_timestamp": long,
"exposure_characteristics_locator": string,
"policy_characteristics_locator": string,
"indemnity_per_item": number,
"indemnity_per_event": number,
"indemnity_in_aggregate": number,
"lump_sum_payment": number,
"deductible": number,
"premium": number,
"technical_premium": number // Optional
"coverage_start_timestamp": long,
"coverage_end_timestamp": long,
"original_coverage_end_timestamp": long,
"field_values": ValuesMap,
"field_groups_by_locator": map<String, ValuesMap>,
"end_change_bound": long,
"policy_modification_locator": string,
"policyholder_locator": string,
"policy_locator": string,
"created_timestamp": long,
"updated_timestamp": long
}
],
"created_timestamp": long,
"updated_timestamp": long
}
],
"created_timestamp": long,
"updated_timestamp": long
}
]
data.policy.modifications
[
{
"locator": string,
"name": string,
"display_id": string,
"number": integer,
"issued_timestamp": long,
"new_policy_characteristics_locator": string,
"exposure_modifications": [
{
"locator": string,
"new_exposure_characteristics_locator": string,
"peril_modifications": [
{
"locator": string,
"peril_locator": string,
"exposure_modification_locator": string,
"new_peril_characteristics_locator": string,
"replaced_peril_characteristics_locator": string,
"premium_change": number
}
]
}
],
"created_timestamp": long,
"updated_timestamp": long
}
]
data.policy.invoices
[
{
"locator": string,
"type": string,
"display_id": string,
"created_timestamp": long,
"updated_timestamp": long,
"number": integer,
"current_status": string,
"statuses": [
{
"status": string,
"timestamp": long,
"account_locator": string
}
],
"due_timestamp": long,
"total_due": number,
"total_due_currency": string,
"payments": [
{
"payment_locator": string,
"amount": number,
"timestamp": long
}
]
}
]
data.policy.fees
[
{
"name": string,
"amount": number,
"amount_currency": string,
"description": string
}
]
data.policy.commissions
[
{
"peril_characteristics_locator": string,
"peril_commissions": [{}]
}
]
data.policy.commissions.peril_commissions
[
{
"amount": number,
"amount_currency": string,
"recipient": string
}
]