Underwriting

Overview

As discussed in the main feature guide, Underwriting is the process that determines whether some prospective transaction is acceptable to the business, considering risk and any other relevant factors.

The basic structure:

1. A set of flags can be added to a quote or policy transaction, via API or this plugin. 1. The platform interprets these flags to make a decision about the transaction’s ability to proceed.

In the underwriting plugin, you implement the logic to interpet, add new, or clear flags. Existing flags may have been set via API before the execution of the plugin.

The plugin configuration follows the same override method approach as for other plugins described in the plugin overview.

Configuration

The underwriting plugin requires that an interface be implemented for both quotes and policy transactions of each Product defined in the configuration.

Example Interfaces:

  • Configuration has a top-level config.json shown below

  • Configuration has a top-level plugins/java folder containing UnderwritingPluginImpl.java

Sample contents of the top-level config.json file defining various entity types:

{
    "products": {
        "personalAuto": {
            "eligibleAccountTypes": ["consumerAccount"]
            "data": {}
    }
        "termLife": {
            "eligibleAccountTypes": ["consumerAccount"]
            "data": {}
    }
}

Example method implementations in the UnderwritingPluginImpl.java file:

package com.socotra.deployment.customer; // Must include

// Must implement UnderwritingPlugin, which defines interfaces and default method implementations for override
public class UnderwritingPluginImpl implements UnderwritingPlugin {

    // Method for underwriting quotes based on the personalAuto product
    @Override
    public UnderwritingModification underwrite(PersonalAutoQuoteRequest personalAutoQuoteRequest) {

    return UnderwritingModification.builder()
            .flagsToCreate(List.of(UnderwritingFlagCore.builder()
            .level(UnderwritingLevel.approve)
            .build()))
        .build();
    }

    // Method for underwriting policy transactions based on the personalAuto product
    @Override
    public UnderwritingModification underwrite(PersonalAutoRequest personalAutoRequest) {

    return UnderwritingModification.builder()
            .flagsToCreate(List.of(UnderwritingFlagCore.builder()
            .level(UnderwritingLevel.approve)
            .build()))
        .build();
    }

    // Method for underwriting quotes based on the termLife product
    @Override
    public UnderwritingModification underwrite(TermLifeQuoteRequest termLifeQuoteRequest) {

    return UnderwritingModification.builder()
            .flagsToCreate(List.of(UnderwritingFlagCore.builder()
            .level(UnderwritingLevel.approve)
            .build()))
        .build();
    }

    // Method for underwriting policy transactions based on the termLife product
    @Override
    public UnderwritingModification underwrite(TermLifeRequest termLifeRequest) {

    return UnderwritingModification.builder()
            .flagsToCreate(List.of(UnderwritingFlagCore.builder()
            .level(UnderwritingLevel.approve)
            .build()))
        .build();
    }

Return Object

Each method should return an UnderwritingModification object containing an array of underwriting flag items: <Collection>UnderwritingFlagCore.

The example below shows how an UnderwritingFlagCore can be constructed, what properties it should have, and, in the context of underwriting a quote based on a personalAuto product, how it can be added to and returned as part of a UnderwritingModification:

package com.socotra.deployment.customer; // Must include

// Must implement UnderwritingPlugin
public class UnderwritingPluginImpl implements UnderwritingPlugin {

// Set a threshold value
private final BigDecimal VALUE_THRESHOLD = BigDecimal.valueOf(100000);

@Override
public UnderwritingModification underwrite(PersonalAutoQuoteRequest request) {

    // Init some variables
    BigDecimal maxValue = BigDecimal.ZERO;
    String vin = "";
    ULID elementLocator = null;

    // Establish vehicle with highest value
    for (PersonalVehicleQuote vq : quote.personalVehicles()) {
        PersonalVehicleQuote.PersonalVehicleQuoteData data = vq.data();
        if (maxValue.compareTo(data.value()) < 0) {
            maxValue = data.value();
            vin = data.VIN();
            elementLocator = vq.locator();
        }
    }

    // Check if the vehicle with the highest value exceeds the threshold
    if (maxValue.compareTo(VALUE_THRESHOLD) >= 0) {
        return UnderwritingModification.builder()
            .flagsToCreate(List.of(UnderwritingFlagCore.builder()
                .level(UnderwritingLevel.decline)
                .note("Vehicle's value is above the threshold of " + VALUE_THRESHOLD.toString() + " for VIN " + vin)
                .elementLocator(elementLocator)
                .build()))
            .build();
    }
    return UnderwritingModification.builder()
            .flagsToCreate(List.of(UnderwritingFlagCore.builder()
            .level(UnderwritingLevel.approve)
            .build()))
        .build();
}