Installments Plugin
The Installments Plugin allows you to adjust the generateTime, dueTime, and autopayTime of installments generated from installment lattices to suit business needs.
For example, installment timing may vary based on product type, first-time payments on new policies, or disruptions to installment schedules.
The Installments Plugin is triggered after installments are generated. Installments are generated from installment lattices after a quote or policy transaction is issued.
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 InstallmentsPluginImpl.java in the example below, but you can name your class whatever you’d like.
Implement the InstallmentsPlugin interface, and override the method corresponding to your target product type.
For example, the following class contains a method that adjusts installments for commercial auto quotes and policy transactions.
public class InstallmentsPluginImpl implements InstallmentsPlugin {
private static final Logger log = LoggerFactory.getLogger(InstallmentsPluginImpl.class);
// Adjusts installments for commercial auto quotes and policy transactions
@Override
public InstallmentsPluginResponse updateInstallments(CommercialAutoRequest commercialAutoRequest) {
Map<String, InstallmentUpdate> installmentUpdates = new HashMap<>();
return InstallmentsPluginResponse.builder().installmentUpdates(installmentUpdates).build();
}
}
The method argument contains an InstallmentLattice object, Installment objects, and an InstallmentsPluginContext object. The InstallmentsPluginContext object contains the following fields:
accountLocator- The account locatorquoteLocator- The quote locatorpolicyLocator- The policy locatortransactionLocator- The policy transaction locator
The method returns an InstallmentsPluginResponse object, which contains a map between installment locators and InstallmentUpdate objects. Each InstallmentUpdate object contains the following fields:
generateTime- When an invoice for the installment will be generateddueTime- When the invoice is dueautopayTime- When autopay logic is executed, if the Autopay Plugin has been implemented
For each of these fields, if no value is specified, the original value will be used, unless it needs to be adjusted based on the adjustment rules.
Installments with the same generateTime and dueTime will be combined into the same invoice when the generateTime is reached.
Additional data can be retrieved using the Plugin Data Fetcher.
Adjustment Rules
The values for the generateTime, dueTime, and autopayTime fields will be automatically adjusted after plugin execution is complete based on the following rules:
If the
generateTimeis after thedueTime, thegenerateTimewill be set to thedueTime.If the
autopayTimeis not betweengenerateTimeanddueTime, theautopayTimewill be set to either thegenerateTimeor one day before thegenerateTime, whichever is later.
Execution
The Installments Plugin is triggered after installments are generated. Installments are generated from installment lattices after a quote or policy transaction is issued.
Example
The following example is based on the Prism configuration. Contact your Socotra representative for more information.
// Adjusts the generate time to the beginning of the next month
@Override
public InstallmentsPluginResponse updateInstallments(CommercialAutoRequest commercialAutoRequest) {
Map<String, InstallmentUpdate> installmentUpdates = movePastInstallmentsToNextMonth(commercialAutoRequest);
return InstallmentsPluginResponse.builder().installmentUpdates(installmentUpdates).build();
}
private Map<String, InstallmentUpdate> movePastInstallmentsToNextMonth(CommercialAutoRequest commercialAutoRequest) {
InstallmentsPluginContext context = commercialAutoRequest.context();
Collection<Installment> installments = commercialAutoRequest.installments();
InstallmentLattice installmentLattice = commercialAutoRequest.installmentLattice();
log.info(
"Received InstallmentsPlugin request for context: {}, installments: {} and installmentLattice: {}",
context,
installments,
installmentLattice);
DataFetcher dataFetcher = DataFetcher.getInstance();
Policy policy = dataFetcher.getPolicy(context.policyLocator().orElseThrow());
Instant now = Instant.now();
ZoneId zoneId = ZoneId.of(policy.timezone());
ZonedDateTime zonedDateTime = now.atZone(zoneId);
ZonedDateTime nextMonthDayOne = zonedDateTime.plusMonths(1).withDayOfMonth(1).toLocalDate().atStartOfDay(zoneId);
Instant newGenerateTime = nextMonthDayOne.toInstant();
Map<String, InstallmentUpdate> installmentUpdates = new HashMap<>();
for (Installment installment : installments) {
if (installment.generateTime().isBefore(newGenerateTime)) {
InstallmentUpdate update =
InstallmentUpdate.builder()
.generateTime(newGenerateTime)
.dueTime(newGenerateTime.plusMillis(Duration.between(installment.generateTime(), installment.dueTime()).toMillis()))
.build();
installmentUpdates.put(installment.locator().toString(), update);
log.info(
"Updated installment {} to new generate time {} and due time {}",
installment.locator(),
newGenerateTime,
update.dueTime());
} else {
log.info(
"Installment {} was not updated because the old generate time {} is after the new generate time {}",
installment.locator(),
installment.generateTime(),
newGenerateTime);
}
}
log.info("Returning installment updates: {}", installmentUpdates);
return installmentUpdates;
}