Documents
Overview
The Document production and management system in Socotra provides controls to author and render documents that can be attached to quotes, policies, or invoices.
Document Scope
Each document has a scope
setting for how it should be interpreted based on the transaction history. Like other policy data, each instance of a document may be considered to be “in-force” based on whether the transaction that has created it has been issued, or whether it has been superseded by another transaction. The scope options provide additional controls for this determination. The choices for scope are:
transaction
: The document is local to the transaction and is never considered to be “on the policy.”policy
: The document is considered on the policy when the transaction that creates it is issued, and will remain on the policy until a subsequent transaction removes it.term
: The same aspolicy
, except all previously-existing documents with this scope are automatically removed on renewals.segment
: The document is local to a segment, and does not carry over to following segments.invoice
: The document is specifically used for invoice documents.
Policy Document Workflow
Tenants may be configured so that when a quote or policy transaction reaches any or all of the validated
, priced
, underwritten
, accepted
, or issued
states, documents are created based on the state of the data for the quote or transaction at that time. These state transitions are called “triggers” for documents. Each document type configured is based on one of these triggers, and each product can have a different set of documents created.

The Document Selection Plugin determines which of the documents available (based on configuration) should be produced. The Data Snapshot Plugin assembles all the data needed to render it and the metadata that should be maintained alongside it. The Socotra renderer then produces the actual .pdf, .html, or .txt file based on the template referenced in the document definition. If the selection plugin indicates that multiple documents are to be created, each one is handled in parallel with separate calls to the data snapshot plugin.
Note
Static documents do not have a rendering step, so there is no rendering data captured. The data snapshot plugin still is used to assemble any desired metadata.
Each transaction has properties related to documents:
transactionDocuments
: This is an array of locators of documents generated by the transaction that havescope
equal totransaction
.newPolicyDocuments
: An array of locators of new documents generated by this transaction that have scope other thantransaction
.carryForwardPolicyDocuments
: The locators of documents carried forward because they are on the transaction’sbasedOn
transaction and haven’t been removed based on scope logic.
For any document, the carryForwardPolicyDocuments
property will be the transaction’s basedOn
transaction’s newPolicyDocuments
combined with its carryForwardPolicyDocuments
that remain on the policy.
Quotation
Quotes work similarly to policy transactions except that there is no transaction history and therefore no existing documents to consider. transaction
scoped documents will remain attached to the quote itself and not transfer to the policy on issuance; other documents will be copied over to the policy issuance transaction and therefore deemed to be on the policy.
Because there is no history for a quote, quotes will not have a carryForwardPolicyDocuments
property, though they will have transactionDocuments
and newPolicyDocuments
.
Static and Dynamic Documents
Static documents are configured with the rendering
value prerendered
. As the name implies, static documents do not have variable content. Dynamic documents, on the other hand, are indicated with rendering
value dynamic
, passing through an extra rendering step that takes the document as a template and fills out the final form according to logic specified in the template.
Dynamic document templates may use either the Liquid or Velocity templating languages. Socotra currently supports Liquid 5.5.0 and Velocity 2.3.
See the Dynamic Documents Guide for further details, including examples and guidance on inspecting rendering data and troubleshooting.
Document Consolidation
You can configure the automatic consolidation of multiple documents into a single artifact with additional features such as a cover page, table of contents, and page numbering.
To do so, set up the top-level ConsolidatedDocumentConfigRef configuration, adding the name of your consolidated document configuration to the documents
set for applicable products’ (ProductRef). The consolidated document trigger will match the latest trigger time of its subdocuments, and cannot be included as a subdocument itself (i.e., no deep “nesting” for document consolidation).
Subdocuments continue to be produced independently of the consolidated document, and can be fetched separately from the consolidated document.
Example
Suppose you have already defined a “WelcomePage” document and a “LegalDisclosures” document, and would like the two to be produced as a single “DocPackage” set. You would define “DocPackage” in ConsolidatedDocumentConfigRef like this:
{
"DocPackage": {
"consolidatedDocuments": ["WelcomePage", "LegalDisclosures"]
}
}
And then add “DocPackage” to the applicable ProductRef documents
array:
{
"displayName" : "Commercial Auto",
// ...,
"documents": ["WelcomePage", "LegalDisclosures", "DocPackage"],
// ...,
}
You’ll see the consolidated document produced as a distinct entity from its subdocuments, triggered at the same time as the latest trigger among the documents in its subdocument set (i.e., a consolidated document’s trigger is inferred from its subdocuments).
If the above “DocPackage” set had been produced at quote issuance, you could expect to see a result like the following – note that the consolidated document references the subdocuments, and each subdocument references the consolidated document in consolidatedTo
:
[
{
"locator": "01JT3P746EMZZ8J7KSMPQS36NZ",
"referenceLocator": "01JT3P6QK4R4VXNJKR0TYRYZ1F",
"referenceType": "quote",
"staticName": "DocPackage",
"documentInstanceState": "ready",
// ...,
"external": false,
"consolidatedFrom": [
"01JT3P6TNR1A0EWF5P83AEDJNG",
"01JT3P6TNSTP758DG9CTV63PJZ"
]
},
{
"locator": "01JT3P6TNR1A0EWF5P83AEDJNG",
"referenceLocator": "01JT3P6QK4R4VXNJKR0TYRYZ1F",
// ...,
"consolidatedTo": [
"01JT3P746EMZZ8J7KSMPQS36NZ"
]
},
{
"locator": "01JT3P6TNSTP758DG9CTV63PJZ",
"referenceLocator": "01JT3P6QK4R4VXNJKR0TYRYZ1F",
// ...,
"consolidatedTo": [
"01JT3P746EMZZ8J7KSMPQS36NZ"
]
}
]
Plugins
Policy Document Selection Plugin
The Document Selection Plugin decides which documents will be attached to a quote or policy transaction, with eligibility determined by the product’s configuration. For each potential document, the plugin will select one of:
generate
: Always creates a new document, which will replace that document (if any) in the document’s scope.noChange
: Leaves the existing document in place, if any.generateIfAbsent
: LikenoChange
if the document already exists in the scope, or likegenerate
if it does not yet exist.remove
: Removes the document if it already exists.
When we say “the document” we mean any instance of the specific document declared in configuration, for the scope for that document. In other words, the basis for the equivalence check is the staticName
of the document. The instance could change with versioned resource selection. For example, if we have a document declared with static name newJerseyDisclosures
with term
scope, and that document has V1, V2, and V3 variations, the above choices would be based on comparing documents in the term by “newJerseyDisclosures” and NOT “newJerseyDisclosuresV1”.
For documents configured with scope
equal to transaction
or segment
, generateIfAbsent
will always behave the same as generate
, and remove
will have no effect. This is because these documents are local to the transaction itself.
For the purposes of document scope handling, the definition of “the document exists” is that a document with that static name is contained within the “previous segment” and has policy
scope, or has term
scope and the new segment does not start at beginning of a term, so it will carry forward unless explicitly removed or re-generated. The “previous segment” is the pre-split segment for the transaction if there is one, or the first segment lower in the transaction stack that has endTime
equal to the new segment’s startTime
.
Document Data Snapshot Plugin
The Document Data Snapshot Plugin will assemble the metadata, and if dynamic, the rendering data for the document.
After the results of this plugin call are persisted, the document will have dataReady
state if it is a dynamic document, or ready
state if it is static. This plugin is executed asynchronously with any client request.
For dynamic documents, when they are rendered to PDF form, the state will change from dataReady
to ready
.
Note
The dataReady
state is transient; generally documents will be first seen in ready
state.
Document Consolidation Snapshot Plugin
The Document Consolidation Plugin allows for the assembly of rendering data and metadata, just like the Document Data Snapshot Plugin.