# Document Data Snapshot Plugin



The Document Data Snapshot Plugin allows you to add metadata to static and dynamic [documents](/configuration/resources/documents). It can also be used to add data to [dynamic documents](/features/documents/dynamic-documents).

This plugin will be automatically executed as part of the [policy document workflow](/configuration/resources/documents#policy_document_workflow) for quotes and policies, and before [invoice rendering](/features/billing/invoicing#invoiceRendering). The Document Data Snapshot Plugin will be triggered after the [Document Selection Plugin](/configuration/plugins/document-selection) has been successfully executed. Document workflows can be customized through <ApiLink name="DocumentConfigRef" /> configuration objects.

This plugin will also be executed when manually rendering documents using the <ApiLink name="renderDocument">Render Document</ApiLink> API endpoint.

Once this plugin has been successfully executed and the specified document has been updated, the document will transition to a new state: Dynamic documents will move to the `dataReady` state, and static documents will move to the `ready` state. Dynamic documents will move to the `ready` state after rendering.

This plugin is executed asynchronously.

Supported Entity Types [#supported-entity-types]

The Document Data Snapshot Plugin supports the following entity types:

* Quotes
* Policy Transactions
* Invoices

Implementation [#implementation]

Create a new Java class in the `src/main/java/com/socotra/deployment/customer` folder. All plugin code must be contained within this folder. We named our class `DocumentDataSnapshotPluginImpl.java` in the example below, but you can name your class whatever you'd like.

Implement the `DocumentDataSnapshotPlugin` interface, and override the method corresponding to your target entity type.

For example, the following class adds data and metadata to documents for commercial auto quotes:

```java
public class DocumentDataSnapshotPluginImpl implements DocumentDataSnapshotPlugin {
    private static final Logger log = LoggerFactory.getLogger(DocumentDataSnapshotPluginImpl.class);

    // Add data and metadata to documents for commercial auto quotes

    @Override
    public DocumentDataSnapshot dataSnapshot(CommercialAutoQuoteRequest commercialAutoQuoteRequest) {
        CommercialAutoQuote commercialAutoQuote = commercialAutoQuoteRequest.quote();

        HashMap<String, String> metadata = new HashMap<>();
        metadata.put("exampleKey", "exampleValue");

        HashMap<String, Object> renderingData = new HashMap<>();
        renderingData.put("quote", commercialAutoQuote);

        return DocumentDataSnapshot.builder().metadata(metadata).renderingData(renderingData).build();
    }
}
```

The method argument contains the entity. In this case, the entity is a commercial auto quote.

The method returns a `DocumentDataSnapshot` object, which contains the `metadata` and `renderingData` to be added to all documents for your target entity type. `metadata` will be added to both static documents and dynamic documents. `renderingData` contains data that can only be rendered by dynamic documents.

<span id="documentDataSnapshotExample" />

Examples [#examples]

All examples are based on the Prism configuration. Contact your Socotra representative for more information.

Quote [#quote]

```java
// Add data and metadata to documents for commercial auto quotes

@Override
public DocumentDataSnapshot dataSnapshot(CommercialAutoQuoteRequest commercialAutoQuoteRequest) {
    CommercialAutoQuote commercialAutoQuote = commercialAutoQuoteRequest.quote();
    QuotePricing pricing = DataFetcherFactory.get().getQuotePricing(commercialAutoQuote.locator());
    HashMap<String, Object> renderingData = new HashMap<>();

    DecimalFormat df = new DecimalFormat("0.00");

    BigDecimal premiumTotal = BigDecimal.ZERO;
    BigDecimal otherTotal = BigDecimal.ZERO;

    if (pricing != null && pricing.items() != null) {
        for (Charge item : pricing.items()) {
            if ("premium".equalsIgnoreCase(item.chargeCategory().toString())) {
                premiumTotal = premiumTotal.add(item.amount());
            } else if (!"nonFinancial".equalsIgnoreCase(item.chargeCategory().toString())) {
                otherTotal = otherTotal.add(item.amount());
            }
        }
    }

    BigDecimal totalBillable = premiumTotal.add(otherTotal);

    HashMap<String, Object> enhancedPricing = new HashMap<>();

    enhancedPricing.put("premiumTotal", df.format(premiumTotal));
    enhancedPricing.put("otherTotal", df.format(otherTotal));
    enhancedPricing.put("totalBillable", df.format(totalBillable));

    renderingData.put("quote", commercialAutoQuote);
    renderingData.put("pricing", enhancedPricing);
    renderingData.put("productType", "CommercialAuto");

    HashMap<String, String> metadata = new HashMap<>();
    metadata.put("accountLocator", commercialAutoQuote.accountLocator().toString());

    return DocumentDataSnapshot.builder()
            .metadata(metadata)
            .renderingData(renderingData)
            .build();
}
```

Policy Transaction [#policy-transaction]

```java
// Add data and metadata to documents for commercial auto policies

@Override
public DocumentDataSnapshot dataSnapshot(CommercialAutoRequest commercialAutoRequest) {
    Policy policy = commercialAutoRequest.policy();
    Transaction transaction = commercialAutoRequest.transaction();
    CommercialAutoSegment segment = commercialAutoRequest.segment().orElse(null);

    if (segment == null) {
        log.error("Segment is missing in the commercial auto request");
    }

    HashMap<String, Object> renderingData = new HashMap<>();

    String pattern = "MM/dd/yyyy";
    DateFormat dateFormatter = new SimpleDateFormat(pattern);
    Date today = Calendar.getInstance().getTime();

    String todayAsString = dateFormatter.format(today);

    renderingData.put("todayAsString", todayAsString);
    renderingData.put("policy", policy);
    renderingData.put("transaction", transaction);
    renderingData.put("segment", segment);
    renderingData.put("productType", "CommercialAuto");

    HashMap<String, String> metadata = new HashMap<>();
    metadata.put("productType", "CommercialAuto");

    return DocumentDataSnapshot.builder()
            .metadata(metadata)
            .renderingData(renderingData)
            .build();

}
```

Invoice [#invoice]

```java
// Add data and metadata to invoices

@Override
public DocumentDataSnapshot dataSnapshot(InvoiceDetailsRequest invoiceDetailsRequest) {
    NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
    InvoiceDetails invoiceDetails = invoiceDetailsRequest.invoiceDetails();

    Map<String, Object> renderingData = new HashMap<>();

    String formattedTotalAmount = currencyFormat.format(invoiceDetails.totalAmount());
    String formattedTotalRemainingAmount = currencyFormat.format(invoiceDetails.totalRemainingAmount());

    renderingData.put("startTime", invoiceDetails.startTime());
    renderingData.put("endTime", invoiceDetails.endTime());
    renderingData.put("totalAmount", formattedTotalAmount);
    renderingData.put("totalRemainingAmount", formattedTotalRemainingAmount);

    HashMap<String, String> metadata = new HashMap<>();
    metadata.put("totalRemainingAmount", formattedTotalRemainingAmount);

    return DocumentDataSnapshot.builder()
            .metadata(metadata)
            .renderingData(renderingData)
            .build();
}
```

Next Steps [#next-steps]

* [Document Selection Plugin](/configuration/plugins/document-selection)

See Also [#see-also]

* [Plugins Overview](/configuration/plugins/overview)
* [Documents](/configuration/resources/documents)
* [Dynamic Documents](/features/documents/dynamic-documents)
* [Policy Document Workflow](/configuration/resources/documents#policy_document_workflow)
* [Invoice Rendering](/features/billing/invoicing#invoiceRendering)
* <ApiLink name="DocumentConfigRef" />
* <ApiLink name="renderDocument" />
