Refactor doPrecheck method to improve parameter handling and enhance error messages with calculation date support.

This commit is contained in:
Jan 2025-12-09 10:55:01 +01:00
parent 4f0eeff16b
commit 0edcfb5258

View file

@ -6,6 +6,7 @@ import de.avatic.lcc.model.db.nodes.Node;
import de.avatic.lcc.model.db.premises.Premise;
import de.avatic.lcc.model.db.premises.route.Destination;
import de.avatic.lcc.model.db.premises.route.Route;
import de.avatic.lcc.model.db.premises.route.RouteNode;
import de.avatic.lcc.model.db.premises.route.RouteSection;
import de.avatic.lcc.model.db.properties.PropertySet;
import de.avatic.lcc.model.db.properties.SystemPropertyMappingId;
@ -28,6 +29,7 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@ -75,8 +77,11 @@ public class PreCalculationCheckService {
this.eUTaxationResolverService = eUTaxationResolverService;
}
@Async("calculationExecutor")
public CompletableFuture<Void> doPrecheck(Integer premiseId, Integer setId, Integer periodId) {
public void doPrecheck(Integer premiseId, Optional<PropertySet> set, Optional<ValidityPeriod> period) {
doPrecheck(premiseId, set, period, LocalDate.now());
}
public void doPrecheck(Integer premiseId, Optional<PropertySet> set, Optional<ValidityPeriod> period, LocalDate date) {
var premise = premiseRepository.getPremiseById(premiseId).orElseThrow();
supplierCheck(premise);
@ -93,7 +98,6 @@ public class PreCalculationCheckService {
throw new PremiseValidationError("No destination defined yet, please add at least one destination.");
}
for (Destination destination : destinations) {
var node = nodeRepository.getByDestinationId(destination.getId()).orElseThrow();
@ -117,24 +121,16 @@ public class PreCalculationCheckService {
throw new PremiseValidationError("Door-2-door lead time not entered or zero.");
}
var period = validityPeriodRepository.getById(periodId);
var set = propertySetRepository.getById(setId);
periodCheck(period, set);
periodCheck(period.orElse(null), set.orElse(null), date);
routes.stream().filter(Route::getSelected).findAny().ifPresent(r -> {
var sections = routeSectionRepository.getByRouteId(r.getId());
routeCheck(sections, period);
routeCheck(sections, period.orElseThrow(), date);
});
}
}
return CompletableFuture.completedFuture(null);
}
private void periodCheck(ValidityPeriod period, PropertySet set) {
private void periodCheck(ValidityPeriod period, PropertySet set, LocalDate calculationDate) {
if (set == null)
throw new PremiseValidationError("There are no system properties for the given date. Please contact your administrator.");
@ -148,7 +144,9 @@ public class PreCalculationCheckService {
if (ValidityPeriodState.VALID != set.getState() && ValidityPeriodState.EXPIRED != period.getState())
throw new PremiseValidationError("There are no valid system properties for the given date. Please contact your administrator.");
//TODO: sicherstellen, dass die valid days für den zeitpunkt galten zu dem die valid period galt (wenn rückwirkend gerechnet wird)
if (calculationDate == null) {
var validDays = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.VALID_DAYS, set.getId());
var renewals = period.getRenewals();
@ -159,10 +157,11 @@ public class PreCalculationCheckService {
if (!period.getStartDate().plusDays((((long) validDaysInt * renewals) + validDaysInt)).isAfter(LocalDateTime.now()))
throw new PremiseValidationError("There are no valid rates for the given date. Please contact your administrator.");
}
}
private void routeCheck(List<RouteSection> sections, ValidityPeriod period) {
private void routeCheck(List<RouteSection> sections, ValidityPeriod period, LocalDate calculationDate) {
sections.forEach(section -> {
var fromRouteNode = routeNodeRepository.getFromNodeBySectionId(section.getId());
@ -173,27 +172,22 @@ public class PreCalculationCheckService {
if (RateType.MATRIX == section.getRateType()) {
var rate = matrixRateRepository.getByCountryIds(fromRouteNode.get().getCountryId(), toRouteNode.get().getCountryId(), period.getId());
if (rate.isEmpty()) {
var toText = period.getEndDate() == null ? "" : " to " + period.getEndDate().format(DateTimeFormatter.ISO_DATE);
throw new PremiseValidationError("The transport rates for the period " + period.getStartDate().format(DateTimeFormatter.ISO_DATE) + toText + " are insufficient to perform the calculation for route segment" + fromRouteNode.get().getExternalMappingId() + " to " + toRouteNode.get().getExternalMappingId());
}
constructRouteSectionError(calculationDate, fromRouteNode.get(), toRouteNode.get(), rate.isEmpty());
}
if (RateType.CONTAINER == section.getRateType()) {
var rate = containerRateRepository.findRoute(fromRouteNode.get().getNodeId(), toRouteNode.get().getNodeId(), period.getId(), section.getTransportType());
if (rate.isEmpty()) {
var toText = period.getEndDate() == null ? "" : " to " + period.getEndDate().format(DateTimeFormatter.ISO_DATE);
throw new PremiseValidationError("The transport rates for the period " + period.getStartDate().format(DateTimeFormatter.ISO_DATE) + toText + " are insufficient to perform the calculation for route segment" + fromRouteNode.get().getExternalMappingId() + " to " + toRouteNode.get().getExternalMappingId());
constructRouteSectionError(calculationDate, fromRouteNode.get(), toRouteNode.get(), rate.isEmpty());
}
}
});
}
private void constructRouteSectionError(LocalDate calculationDate, RouteNode fromRouteNode, RouteNode toRouteNode, boolean empty) {
if (empty) {
var dateStr = calculationDate == null ? "" : String.format("on given date %s", calculationDate.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")));
var errStr = String.format("Missing transport rate for route section %s to %s %s. Please contact your admin.", fromRouteNode.getExternalMappingId(), toRouteNode.getExternalMappingId(), dateStr);
throw new PremiseValidationError(errStr);
}
}
private void destinationCheck(Destination destination, Node node) {