Part 2: Using Tables and Formulas
Implementing Premium Computation
In this chapter we will implement the premium computation for our home contents products.
We will extend our model to include the attributes and methods shown in the following figure.
Each coverage is subject to an annual base premium. An annual base premium is the net premium payable per annum, insurance tax and surcharges not included. The contract’s annual base premium is the total value of all coverages' annual base premiums.
The contract’s netPremiumPm is the net premium due per payment. It is the result of the annual base premium plus an installment surcharge (if the premium is not paid annually), divided by the number of payments, e.g., 12 in the case of monthly payment.
The grossPremiumPm is the gross premium due per payment, i.e. including insurance tax. It amounts to the netPremiumPm times 1+insurance tax rate. For the sake of simplicity, we will assume in this tutorial that the installment surcharge is always 3% and the insurance tax is always 19%.
Your next task will be to create the new attributes in the classes HomeContract
and HomeBaseCoverage
. We will leave the HomeExtraCoverages for the next chapter. All attributes are derived (cached) and of the type Money. Because they are cached, derived attributes, Faktor-IPS generates one member variable and one getter method for each attribute.
All premium attributes are computed by the computePremium()
method of the HomeContract
class. This method is able to compute all premium attributes of the contract, as well as the annual base premium of the coverages. To do this, of course, it uses the computeAnnualBasePremium()
method of the coverages.
You can now create these methods on the second editor page for the HomeContract
and HomeBaseCoverage
classes. The dialog box for editing a method signature is shown in the next figure.
Generating code offers more advantages for relationships and attributes than for methods. Hence, methods can, of course, also be defined directly in the source code.
The following code snippet shows the premium computation implementation in the HomeContract
class. For the sake of clarity, we will implement the computation of the annual base premium and the netPremiumPm in two separate, private methods that will be written directly in the source code, but not added to the model.
/**
* @generated NOT
*/
@IpsGenerated
public void computePremium() {
computeAnnualBasePremium();
computeNetPremiumPm();
Decimal taxMultiplier = Decimal.valueOf(119, 2); // 1 + 19% tax rate
grossPremiumPm = netPremiumPm.multiply(taxMultiplier, RoundingMode.HALF_UP);
}
private void computeAnnualBasePremium() {
annualBasePremium = Money.euro(0, 0);
HomeBaseCoverage baseCoverage = getHomeBaseCoverage();
baseCoverage.computeAnnualBasePremium();
annualBasePremium = annualBasePremium.add(baseCoverage.getAnnualBasePremium());
/*
* TODO: When extra coverages are added to the model, their premium of course
* has to be added here as well.
*/
}
private void computeNetPremiumPm() {
if (paymentMode == null) {
netPremiumPm = Money.NULL;
return;
}
if (paymentMode.intValue() == 1) {
netPremiumPm = annualBasePremium;
} else {
Decimal factor = Decimal.valueOf(103, 2); // 1 + 0.03 surcharge for non-annual payment
netPremiumPm = annualBasePremium.multiply(factor, RoundingMode.HALF_UP);
}
netPremiumPm = netPremiumPm.divide(paymentMode.intValue(), RoundingMode.HALF_UP);
}
After customizing the code computeAnnualBasePremium();
will be marked as an error. This will be solved in the next step.
Premium Computation for Coverages
For our home contents insurance, the annual base premium computation has to be implemented at the coverages level.
Technically, the annual base rate for the base coverage is computed like this:
-
From the rates table, determine the rate per 1000 Euro sum insured.
-
Divide the sum insured by 1000 Euro and multiply with the premium rate.
As this formula is not subject to change, we will implement it directly in the HomeBaseCoverage Java class. For extra coverages, we will allow the business users to define the annual base premium using computation formulas.
We already defined the method computeAnnualBasePremium()
in the HomeBaseCoverage
class at the beginning of this chapter. Open the Java class HomeBaseCoverage
in the editor and implement the method as follows:
/**
* @generated NOT
*/
@IpsGenerated
public void computeAnnualBasePremium() {
RateTableHome table = getRateTable();
RateTableHomeRow row = null;
if(table!=null) {
row=table.findRow(getHomeContract().getRatingDistrict());
}
if(row==null) {
annualBasePremium=Money.NULL;
return;
}
Money si = getHomeContract().getSumInsured();
Decimal premiumRate = row.getPremiumRate();
annualBasePremium = si.divide(1000, RoundingMode.HALF_UP).multiply(premiumRate, RoundingMode.HALF_UP);
}
We will test the premium computation by extending our JUnit test once more.
@Test
public void testComputePremium() {
// Create a new HomeContract with the products factory method
HomeContract contract = compactProduct.createHomeContract();
// Set contract attributes
contract.setZipcode("45525");
contract.setSumInsured(Money.euro(60_000));
contract.setPaymentMode(2);
// Get the base coverage type that is assigned to the product
HomeBaseCoverageType coverageType = compactProduct.getHomeBaseCoverageType();
// Create the base coverage and add it to the contract
HomeBaseCoverage coverage = contract.newHomeBaseCoverage(coverageType);
// Compute the premium and check the results
contract.computePremium();
// rating district III => premiumRate = 1,21 annualBasePremium = sumInsured /
// 1000 * premiumRate = 60000 / 1000 * 1,21 = 72,60
assertEquals(Money.euro(72, 60), coverage.getAnnualBasePremium());
// contract.annualBasePremium = baseCoverage.annualBasePremium
assertEquals(Money.euro(72, 60), contract.getAnnualBasePremium());
// netPremiumPm = 72,60 / 2 * 1,03 (semi-annual, 3% surcharge) = 37,389 => 37,39
assertEquals(Money.euro(37, 39), contract.getNetPremiumPm());
// grossPremiumPm = 37,39 * taxMultiplier = 37,39 * 1,19 = 44,49
assertEquals(Money.euro(44, 49), contract.getGrossPremiumPm());
}