QuoteCalculator.java
package cl.prgm.portaltrip.domain.service;
import java.math.BigDecimal;
import cl.prgm.portaltrip.domain.model.Quote;
import cl.prgm.portaltrip.domain.model.RiskLevel;
import cl.prgm.portaltrip.domain.model.TripType;
/**
* Quote rules are the same as the ones in travelRules.ts of the frontend.
*/
public class QuoteCalculator {
public static final BigDecimal BASE_PRICE = new BigDecimal("1200");
public static final BigDecimal INSURANCE_PRICE = new BigDecimal("190");
private static final BigDecimal STATION_RATE = new BigDecimal("0.25");
private static final BigDecimal EXTRA_PASSENGER_RATE = new BigDecimal("0.18");
public Quote calculate(
int passengers,
TripType tripType,
boolean insurance,
String locationType,
String dimension,
int residentCount) {
int passengerCount = Math.max(1, passengers);
BigDecimal locationSurcharge = isStation(locationType)
? BASE_PRICE.multiply(STATION_RATE)
: BigDecimal.ZERO;
BigDecimal passengerSurcharge = BASE_PRICE
.multiply(EXTRA_PASSENGER_RATE)
.multiply(BigDecimal.valueOf(Math.max(0, passengerCount - 1)));
BigDecimal tripSurcharge = BASE_PRICE.multiply(tripType.multiplier().subtract(BigDecimal.ONE));
BigDecimal insuranceCost = insurance
? INSURANCE_PRICE.multiply(BigDecimal.valueOf(passengerCount))
: BigDecimal.ZERO;
BigDecimal total = BASE_PRICE
.add(locationSurcharge)
.add(passengerSurcharge)
.add(tripSurcharge)
.add(insuranceCost);
return new Quote(
BASE_PRICE,
locationSurcharge,
passengerSurcharge,
tripSurcharge,
insuranceCost,
total,
riskLevel(dimension, residentCount));
}
public boolean requiresInsurance(String dimension) {
return "unknown".equalsIgnoreCase(dimension);
}
private boolean isStation(String locationType) {
return locationType != null && locationType.toLowerCase().contains("station");
}
private RiskLevel riskLevel(String dimension, int residentCount) {
if (residentCount == 0) {
return RiskLevel.HIGH;
}
if (requiresInsurance(dimension) || residentCount < 5) {
return RiskLevel.MEDIUM;
}
return RiskLevel.LOW;
}
}