From 4b71e88d44e85193040167363312c72d9e147c0b Mon Sep 17 00:00:00 2001 From: kasun Date: Tue, 16 Jun 2026 02:10:12 +0200 Subject: [PATCH] added solution with tariff options as enum and map --- .../com/pfefferminzia/petinsurance/Main.java | 8 ++-- .../petinsurance/animals/Animal.java | 7 +++- .../petinsurance/animals/Dog.java | 6 +++ .../calculations/CalculationResult.java | 5 +++ .../calculations/Calculations.java | 41 +++++++++++++++---- .../calculations/InsuranceContract.java | 29 +++++++++++++ .../calculations/TariffValidator.java | 21 ---------- .../InvalidInsuranceContractException.java | 17 ++++++++ .../TariffNotAvailableException.java | 8 ---- .../petinsurance/tariffs/AgeTariff.java | 27 ++++++++++++ .../tariffs/BreedPremiumAdjustment.java | 18 ++++++++ .../petinsurance/tariffs/Tariff.java | 2 +- 12 files changed, 145 insertions(+), 44 deletions(-) create mode 100644 src/main/java/com/pfefferminzia/petinsurance/calculations/CalculationResult.java create mode 100644 src/main/java/com/pfefferminzia/petinsurance/calculations/InsuranceContract.java delete mode 100644 src/main/java/com/pfefferminzia/petinsurance/calculations/TariffValidator.java create mode 100644 src/main/java/com/pfefferminzia/petinsurance/exception/InvalidInsuranceContractException.java delete mode 100644 src/main/java/com/pfefferminzia/petinsurance/exception/TariffNotAvailableException.java create mode 100644 src/main/java/com/pfefferminzia/petinsurance/tariffs/AgeTariff.java create mode 100644 src/main/java/com/pfefferminzia/petinsurance/tariffs/BreedPremiumAdjustment.java diff --git a/src/main/java/com/pfefferminzia/petinsurance/Main.java b/src/main/java/com/pfefferminzia/petinsurance/Main.java index acee530..360892b 100644 --- a/src/main/java/com/pfefferminzia/petinsurance/Main.java +++ b/src/main/java/com/pfefferminzia/petinsurance/Main.java @@ -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)); } } diff --git a/src/main/java/com/pfefferminzia/petinsurance/animals/Animal.java b/src/main/java/com/pfefferminzia/petinsurance/animals/Animal.java index 0cecd2a..47fe963 100644 --- a/src/main/java/com/pfefferminzia/petinsurance/animals/Animal.java +++ b/src/main/java/com/pfefferminzia/petinsurance/animals/Animal.java @@ -4,7 +4,12 @@ import java.math.BigDecimal; import java.time.LocalDate; public sealed interface Animal permits Dog, Cat, SmallAnimal { - + LocalDate birthday(); + BigDecimal getBaseInsuranceSum(); + + default BigDecimal getPremiumAdjustment() { + return BigDecimal.ZERO; + } } diff --git a/src/main/java/com/pfefferminzia/petinsurance/animals/Dog.java b/src/main/java/com/pfefferminzia/petinsurance/animals/Dog.java index 2ed94b6..40f8156 100644 --- a/src/main/java/com/pfefferminzia/petinsurance/animals/Dog.java +++ b/src/main/java/com/pfefferminzia/petinsurance/animals/Dog.java @@ -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); + } } diff --git a/src/main/java/com/pfefferminzia/petinsurance/calculations/CalculationResult.java b/src/main/java/com/pfefferminzia/petinsurance/calculations/CalculationResult.java new file mode 100644 index 0000000..665b3e7 --- /dev/null +++ b/src/main/java/com/pfefferminzia/petinsurance/calculations/CalculationResult.java @@ -0,0 +1,5 @@ +package com.pfefferminzia.petinsurance.calculations; + +import java.math.BigDecimal; + +public record CalculationResult(BigDecimal insuranceSum, BigDecimal yearlyPremium) {} diff --git a/src/main/java/com/pfefferminzia/petinsurance/calculations/Calculations.java b/src/main/java/com/pfefferminzia/petinsurance/calculations/Calculations.java index c83ba69..224aeaf 100644 --- a/src/main/java/com/pfefferminzia/petinsurance/calculations/Calculations.java +++ b/src/main/java/com/pfefferminzia/petinsurance/calculations/Calculations.java @@ -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); - - BigDecimal insuranceBaseSum = animal.getBaseInsuranceSum(); - return insuranceBaseSum.multiply(tariff.getRate()); + Tariff tariff = contract.tariff(); + + 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)); } } diff --git a/src/main/java/com/pfefferminzia/petinsurance/calculations/InsuranceContract.java b/src/main/java/com/pfefferminzia/petinsurance/calculations/InsuranceContract.java new file mode 100644 index 0000000..5b1d536 --- /dev/null +++ b/src/main/java/com/pfefferminzia/petinsurance/calculations/InsuranceContract.java @@ -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 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); + } + } +} diff --git a/src/main/java/com/pfefferminzia/petinsurance/calculations/TariffValidator.java b/src/main/java/com/pfefferminzia/petinsurance/calculations/TariffValidator.java deleted file mode 100644 index 4fb3ac5..0000000 --- a/src/main/java/com/pfefferminzia/petinsurance/calculations/TariffValidator.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/com/pfefferminzia/petinsurance/exception/InvalidInsuranceContractException.java b/src/main/java/com/pfefferminzia/petinsurance/exception/InvalidInsuranceContractException.java new file mode 100644 index 0000000..3534d7c --- /dev/null +++ b/src/main/java/com/pfefferminzia/petinsurance/exception/InvalidInsuranceContractException.java @@ -0,0 +1,17 @@ +package com.pfefferminzia.petinsurance.exception; + +import java.util.List; + +public class InvalidInsuranceContractException extends RuntimeException { + + private final List violations; + + public InvalidInsuranceContractException(List violations) { + super(String.join("\n", violations)); + this.violations = List.copyOf(violations); + } + + public List getViolations() { + return violations; + } +} diff --git a/src/main/java/com/pfefferminzia/petinsurance/exception/TariffNotAvailableException.java b/src/main/java/com/pfefferminzia/petinsurance/exception/TariffNotAvailableException.java deleted file mode 100644 index f95f4b8..0000000 --- a/src/main/java/com/pfefferminzia/petinsurance/exception/TariffNotAvailableException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.pfefferminzia.petinsurance.exception; - -public class TariffNotAvailableException extends RuntimeException { - - public TariffNotAvailableException(String message) { - super(message); - } -} diff --git a/src/main/java/com/pfefferminzia/petinsurance/tariffs/AgeTariff.java b/src/main/java/com/pfefferminzia/petinsurance/tariffs/AgeTariff.java new file mode 100644 index 0000000..4fde91a --- /dev/null +++ b/src/main/java/com/pfefferminzia/petinsurance/tariffs/AgeTariff.java @@ -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); + } + +} diff --git a/src/main/java/com/pfefferminzia/petinsurance/tariffs/BreedPremiumAdjustment.java b/src/main/java/com/pfefferminzia/petinsurance/tariffs/BreedPremiumAdjustment.java new file mode 100644 index 0000000..168d184 --- /dev/null +++ b/src/main/java/com/pfefferminzia/petinsurance/tariffs/BreedPremiumAdjustment.java @@ -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 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() {} +} diff --git a/src/main/java/com/pfefferminzia/petinsurance/tariffs/Tariff.java b/src/main/java/com/pfefferminzia/petinsurance/tariffs/Tariff.java index 2cc954b..32d73b3 100644 --- a/src/main/java/com/pfefferminzia/petinsurance/tariffs/Tariff.java +++ b/src/main/java/com/pfefferminzia/petinsurance/tariffs/Tariff.java @@ -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;