added modified data driven version
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
package com.pfefferminzia.petinsurance.tariffs;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public enum AgeTariff {
|
||||
UP_TO_TWO(2, new BigDecimal("0.2")), UP_TO_FIVE(5, new BigDecimal("0.25")), UP_TO_SEVEN(7,
|
||||
new BigDecimal("0.28")), OVER_SEVEN(Integer.MAX_VALUE, new BigDecimal("0.3"));
|
||||
|
||||
private final int maxAge;
|
||||
|
||||
private final BigDecimal factor;
|
||||
|
||||
private AgeTariff(int maxAge, BigDecimal factor) {
|
||||
this.maxAge = maxAge;
|
||||
this.factor = factor;
|
||||
}
|
||||
|
||||
public static BigDecimal getFactorForAge(int age) {
|
||||
for (AgeTariff rate : values()) {
|
||||
if (age <= rate.maxAge) {
|
||||
return rate.factor;
|
||||
}
|
||||
}
|
||||
throw new AssertionError("Unexpected age: " + age);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.pfefferminzia.petinsurance.tariffs;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
public final class BreedPremiumAdjustment {
|
||||
|
||||
private static final Map<String, BigDecimal> ADJUSTMENTS = Map.of(
|
||||
"Dackel", new BigDecimal("-0.1"),
|
||||
"Bernhardiner", new BigDecimal("0.1")
|
||||
);
|
||||
|
||||
public static BigDecimal forBreed(String breed) {
|
||||
return ADJUSTMENTS.getOrDefault(breed, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private BreedPremiumAdjustment() {}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.pfefferminzia.petinsurance.tariffs;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public enum Tariff {
|
||||
KOMPAKT(BigDecimal.ONE), OPTIMAL(new BigDecimal("1.2")), PREMIUM(new BigDecimal("1.4"));
|
||||
|
||||
private final BigDecimal rate;
|
||||
|
||||
private Tariff(BigDecimal rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public BigDecimal getRate() {
|
||||
return rate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.pfefferminzia.petinsurance.tariffs;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public record TariffConfiguration(Map<String, BigDecimal> animalBaseSums,
|
||||
Map<String, TariffOption> tariffs, NavigableMap<Integer, BigDecimal> ageFactors,
|
||||
Map<String, BigDecimal> breedFactors) {
|
||||
|
||||
public TariffConfiguration {
|
||||
animalBaseSums = Collections.unmodifiableMap(animalBaseSums);
|
||||
tariffs = Collections.unmodifiableMap(tariffs);
|
||||
ageFactors = Collections.unmodifiableNavigableMap(new TreeMap<>(ageFactors));
|
||||
breedFactors = Collections.unmodifiableMap(breedFactors);
|
||||
}
|
||||
|
||||
public BigDecimal getAnimalBaseSum(String species) {
|
||||
if (species == null || species.isBlank()) {
|
||||
throw new IllegalArgumentException("Tierart darf nicht leer oder null sein.");
|
||||
}
|
||||
|
||||
String normalizedKey = species.trim().toUpperCase();
|
||||
BigDecimal baseSum = animalBaseSums.get(normalizedKey);
|
||||
|
||||
if (baseSum == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Keine Basis-Versicherungssumme für Tierart konfiguriert: " + species);
|
||||
}
|
||||
|
||||
return baseSum;
|
||||
}
|
||||
|
||||
public TariffOption getTariffFactor(String tariffName, LocalDate startDate) {
|
||||
|
||||
TariffOption option = tariffs.get(tariffName.toUpperCase());
|
||||
|
||||
if (option == null) {
|
||||
throw new IllegalArgumentException("Unbekannte Tarifvariante: " + tariffName);
|
||||
}
|
||||
|
||||
if (!option.isAvailableAt(startDate)) {
|
||||
throw new IllegalStateException("Die Tarifvariante " + tariffName + " ist zum "
|
||||
+ startDate + " noch nicht verfügbar.");
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
public BigDecimal getAgeFactor(int age) {
|
||||
if (age < 0) {
|
||||
throw new IllegalArgumentException("Alter kann nicht negativ sein: " + age);
|
||||
}
|
||||
|
||||
var entry = ageFactors.ceilingEntry(age);
|
||||
if (entry == null) {
|
||||
throw new IllegalStateException("Alter überschreitet maximal zulässigen Systemwert.");
|
||||
}
|
||||
|
||||
return entry.getValue();
|
||||
}
|
||||
|
||||
public BigDecimal getBreedFactor(String breed) {
|
||||
if (breed == null || breed.isBlank()) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
return breedFactors.getOrDefault(breed.trim().toUpperCase(), BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.pfefferminzia.petinsurance.tariffs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class TariffLoader {
|
||||
private static final String CONFIG_FILE_NAME = "tariff.properties";
|
||||
|
||||
public static TariffConfiguration loadFromFile() {
|
||||
Properties props = new Properties();
|
||||
|
||||
try (InputStream input =
|
||||
TariffLoader.class.getClassLoader().getResourceAsStream(CONFIG_FILE_NAME)) {
|
||||
if (input == null) {
|
||||
throw new IllegalStateException(
|
||||
"Konfigurationsdatei nicht verfügbar: " + CONFIG_FILE_NAME);
|
||||
}
|
||||
props.load(input);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Fehler beim Auslesen der Tarif-Konfigurationsdatei.",
|
||||
e);
|
||||
}
|
||||
|
||||
return new TariffConfiguration(animalBaseSums(props), tariffs(props), ageFactors(props),
|
||||
breedFactors(props));
|
||||
|
||||
}
|
||||
|
||||
private static Map<String, BigDecimal> animalBaseSums(Properties props) {
|
||||
|
||||
Map<String, BigDecimal> baseSums = new HashMap<>();
|
||||
|
||||
for (String key : props.stringPropertyNames()) {
|
||||
if (key.startsWith("baseSum.")) {
|
||||
String animal = key.substring("baseSum.".length()).toUpperCase();
|
||||
BigDecimal baseSum = new BigDecimal(props.getProperty(key));
|
||||
baseSums.put(animal, baseSum);
|
||||
}
|
||||
}
|
||||
return baseSums;
|
||||
}
|
||||
|
||||
private static Map<String, TariffOption> tariffs(Properties props) {
|
||||
|
||||
return props.stringPropertyNames().stream().filter(key -> key.startsWith("tariffs."))
|
||||
.map(key -> {
|
||||
String name = key.substring("tariffs.".length()).toUpperCase();
|
||||
String[] values = props.getProperty(key).split(",");
|
||||
BigDecimal factor = new BigDecimal(values[0]);
|
||||
LocalDate availableFrom = LocalDate.parse(values[1]);
|
||||
return new TariffOption(name, factor, availableFrom);
|
||||
}).collect(Collectors.toMap(TariffOption::name, tariff -> tariff));
|
||||
}
|
||||
|
||||
private static NavigableMap<Integer, BigDecimal> ageFactors(Properties props) {
|
||||
|
||||
NavigableMap<Integer, BigDecimal> ageFactors = new TreeMap<>();
|
||||
|
||||
for (String key : props.stringPropertyNames()) {
|
||||
if (key.startsWith("age.")) {
|
||||
Integer age = Integer.parseInt(key.replace("age.", ""));
|
||||
BigDecimal factor = new BigDecimal(props.getProperty(key));
|
||||
ageFactors.put(age, factor);
|
||||
}
|
||||
}
|
||||
|
||||
String rawElderly = props.getProperty("elderlyFactor");
|
||||
if (rawElderly == null) {
|
||||
throw new IllegalStateException("Pflichtkonfiguration 'elderlyFactor' fehlt.");
|
||||
}
|
||||
ageFactors.put(Integer.MAX_VALUE, new BigDecimal(rawElderly));
|
||||
return ageFactors;
|
||||
}
|
||||
|
||||
private static Map<String, BigDecimal> breedFactors(Properties props) {
|
||||
|
||||
Map<String, BigDecimal> breedFactors = new HashMap<>();
|
||||
|
||||
for (String key : props.stringPropertyNames()) {
|
||||
if (key.startsWith("breed.")) {
|
||||
String name = key.substring("breed.".length()).toUpperCase();
|
||||
BigDecimal factor = new BigDecimal(props.getProperty(key));
|
||||
breedFactors.put(name, factor);
|
||||
}
|
||||
}
|
||||
return breedFactors;
|
||||
}
|
||||
|
||||
private TariffLoader() {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.pfefferminzia.petinsurance.tariffs;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
public record TariffOption(String name, BigDecimal factor, LocalDate availableFrom) {
|
||||
|
||||
public boolean isAvailableAt(LocalDate date) {
|
||||
return !date.isBefore(availableFrom);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user