added solution with tariff options as enum and map
This commit is contained in:
@@ -2,14 +2,12 @@ package com.pfefferminzia.petinsurance;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import com.pfefferminzia.petinsurance.animals.Dog;
|
||||
import com.pfefferminzia.petinsurance.calculations.Calculations;
|
||||
import com.pfefferminzia.petinsurance.calculations.InsuranceContract;
|
||||
import com.pfefferminzia.petinsurance.tariffs.Tariff;
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Dog dog = new Dog(LocalDate.of(2020, 4, 14), "Husky");
|
||||
Calculations calc = new Calculations();
|
||||
System.out.println(calc.calculateInsuranceSum(dog, Tariff.OPTIMAL, LocalDate.of(2026, 1, 2)));
|
||||
|
||||
System.out.println(new InsuranceContract(new Dog(LocalDate.of(2025, 1, 1), "Dackel"),
|
||||
LocalDate.of(2026, 1, 1), Tariff.OPTIMAL));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,10 @@ import java.time.LocalDate;
|
||||
public sealed interface Animal permits Dog, Cat, SmallAnimal {
|
||||
|
||||
LocalDate birthday();
|
||||
|
||||
BigDecimal getBaseInsuranceSum();
|
||||
|
||||
default BigDecimal getPremiumAdjustment() {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.pfefferminzia.petinsurance.animals;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import com.pfefferminzia.petinsurance.tariffs.BreedPremiumAdjustment;
|
||||
|
||||
public final record Dog(LocalDate birthday, String breed) implements Animal {
|
||||
|
||||
@@ -9,4 +10,9 @@ public final record Dog(LocalDate birthday, String breed) implements Animal {
|
||||
public BigDecimal getBaseInsuranceSum() {
|
||||
return BigDecimal.valueOf(2500.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal getPremiumAdjustment() {
|
||||
return BreedPremiumAdjustment.forBreed(breed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.pfefferminzia.petinsurance.calculations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public record CalculationResult(BigDecimal insuranceSum, BigDecimal yearlyPremium) {}
|
||||
@@ -2,18 +2,43 @@ package com.pfefferminzia.petinsurance.calculations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import com.pfefferminzia.petinsurance.animals.Animal;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import com.pfefferminzia.petinsurance.tariffs.AgeTariff;
|
||||
import com.pfefferminzia.petinsurance.tariffs.Tariff;
|
||||
|
||||
public class Calculations {
|
||||
|
||||
public BigDecimal calculateInsuranceSum(Animal animal, Tariff tariff,
|
||||
LocalDate insuranceStartDate) {
|
||||
public CalculationResult result(InsuranceContract contract) {
|
||||
|
||||
TariffValidator validator = new TariffValidator(insuranceStartDate);
|
||||
validator.checkTariffAvailability(tariff);
|
||||
Tariff tariff = contract.tariff();
|
||||
|
||||
BigDecimal insuranceBaseSum = animal.getBaseInsuranceSum();
|
||||
return insuranceBaseSum.multiply(tariff.getRate());
|
||||
BigDecimal insuranceSum =
|
||||
getInsuranceSum(contract.animal().getBaseInsuranceSum(), tariff.getRate());
|
||||
|
||||
BigDecimal ageFactor =
|
||||
ageFactorLookup(contract.animal().birthday(), contract.insuranceStartDate());
|
||||
|
||||
|
||||
BigDecimal breedPremiumAdjustment = contract.animal().getPremiumAdjustment();
|
||||
|
||||
BigDecimal yearlyPremium = insuranceSum.multiply(ageFactor)
|
||||
.multiply(BigDecimal.ONE.add(breedPremiumAdjustment));
|
||||
|
||||
return new CalculationResult(insuranceSum, yearlyPremium);
|
||||
}
|
||||
|
||||
BigDecimal getInsuranceSum(BigDecimal baseInsuranceSum, BigDecimal tariffRate) {
|
||||
return baseInsuranceSum.multiply(tariffRate);
|
||||
}
|
||||
|
||||
BigDecimal ageFactorLookup(LocalDate birthday, LocalDate insuranceStartDate) {
|
||||
if (insuranceStartDate.isBefore(birthday)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Start der Versicherung kann nicht vor dem Geburtstag sein.");
|
||||
}
|
||||
|
||||
long exactYears = ChronoUnit.YEARS.between(birthday, insuranceStartDate);
|
||||
|
||||
return AgeTariff.getFactorForAge(Math.toIntExact(exactYears));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.pfefferminzia.petinsurance.calculations;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.pfefferminzia.petinsurance.animals.Animal;
|
||||
import com.pfefferminzia.petinsurance.exception.InvalidInsuranceContractException;
|
||||
import com.pfefferminzia.petinsurance.tariffs.Tariff;
|
||||
|
||||
public record InsuranceContract(Animal animal, LocalDate insuranceStartDate, Tariff tariff) {
|
||||
|
||||
private static final LocalDate PREMIUM_AVAILABLE_FROM = LocalDate.of(2026, 7, 1);
|
||||
|
||||
public InsuranceContract {
|
||||
List<String> violations = new ArrayList<>();
|
||||
|
||||
if (animal.birthday().isAfter(insuranceStartDate)) {
|
||||
violations.add("Start der Versicherung kann nicht vor dem Geburtstag sein.");
|
||||
}
|
||||
|
||||
if (insuranceStartDate.isBefore(PREMIUM_AVAILABLE_FROM) && tariff == Tariff.PREMIUM) {
|
||||
violations.add("Die Premium Tarifvariante ist nicht vor dem 1. Juli 2026 verfügbar.");
|
||||
}
|
||||
|
||||
if (!violations.isEmpty()) {
|
||||
throw new InvalidInsuranceContractException(violations);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.pfefferminzia.petinsurance.calculations;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import com.pfefferminzia.petinsurance.exception.TariffNotAvailableException;
|
||||
import com.pfefferminzia.petinsurance.tariffs.Tariff;
|
||||
|
||||
public class TariffValidator {
|
||||
private LocalDate insuranceStartDate;
|
||||
|
||||
public TariffValidator(LocalDate insuranceStartDate) {
|
||||
this.insuranceStartDate = insuranceStartDate;
|
||||
}
|
||||
|
||||
public boolean checkTariffAvailability(Tariff tariff) {
|
||||
if (insuranceStartDate.isBefore(LocalDate.of(2026, 7, 1)) && tariff == Tariff.PREMIUM) {
|
||||
throw new TariffNotAvailableException(
|
||||
"Die Premium Tarifvariante ist nicht vor dem 1. Juli 2026 verfügbar.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.pfefferminzia.petinsurance.exception;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class InvalidInsuranceContractException extends RuntimeException {
|
||||
|
||||
private final List<String> violations;
|
||||
|
||||
public InvalidInsuranceContractException(List<String> violations) {
|
||||
super(String.join("\n", violations));
|
||||
this.violations = List.copyOf(violations);
|
||||
}
|
||||
|
||||
public List<String> getViolations() {
|
||||
return violations;
|
||||
}
|
||||
}
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package com.pfefferminzia.petinsurance.exception;
|
||||
|
||||
public class TariffNotAvailableException extends RuntimeException {
|
||||
|
||||
public TariffNotAvailableException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
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() {}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package com.pfefferminzia.petinsurance.tariffs;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public enum Tariff {
|
||||
KOMPAKT(BigDecimal.ONE), OPTIMAL(BigDecimal.valueOf(1.2)), PREMIUM(BigDecimal.valueOf(1.4));
|
||||
KOMPAKT(BigDecimal.ONE), OPTIMAL(new BigDecimal("1.2")), PREMIUM(new BigDecimal("1.4"));
|
||||
|
||||
private final BigDecimal rate;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user