- Calculations can be started now with any validity period and property set.
- added preflight check for validity period, property set and all route sections
This commit is contained in:
parent
dac371b481
commit
78bd0ad6d6
15 changed files with 318 additions and 131 deletions
|
|
@ -54,10 +54,16 @@ public class CountryPropertyRepository {
|
|||
throw new DatabaseException("Could not update property value for country " + countryId + " and property type " + mappingId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<PropertyDTO> getByMappingIdAndCountryId(CountryPropertyMappingId mappingId, Integer countryId) {
|
||||
return getByMappingIdAndCountryId(mappingId.name(), countryId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<PropertyDTO> getByMappingIdAndCountryId(CountryPropertyMappingId mappingId, Integer setId, Integer countryId) {
|
||||
return getByMappingIdAndCountryId(mappingId.name(), setId, countryId);
|
||||
}
|
||||
|
||||
public Optional<PropertyDTO> getByMappingIdAndCountryId(String mappingId, Integer countryId) {
|
||||
String query = """
|
||||
SELECT type.name as name,
|
||||
|
|
@ -74,14 +80,14 @@ public class CountryPropertyRepository {
|
|||
FROM country_property_type AS type
|
||||
LEFT JOIN (
|
||||
SELECT cp.property_value, cp.country_property_type_id
|
||||
FROM country_property cp
|
||||
JOIN property_set ps ON ps.id = cp.property_set_id
|
||||
FROM country_property cp
|
||||
JOIN property_set ps ON ps.id = cp.property_set_id
|
||||
WHERE cp.country_id = ? AND ps.state = 'DRAFT'
|
||||
) AS draft ON draft.country_property_type_id = type.id
|
||||
LEFT JOIN (
|
||||
SELECT cp.property_value, cp.country_property_type_id
|
||||
FROM country_property cp
|
||||
JOIN property_set ps ON ps.id = cp.property_set_id
|
||||
FROM country_property cp
|
||||
JOIN property_set ps ON ps.id = cp.property_set_id
|
||||
WHERE cp.country_id = ? AND ps.state = 'VALID'
|
||||
) AS valid ON valid.country_property_type_id = type.id
|
||||
WHERE type.external_mapping_id = ?
|
||||
|
|
@ -95,6 +101,36 @@ public class CountryPropertyRepository {
|
|||
return Optional.of(property.getFirst());
|
||||
}
|
||||
|
||||
public Optional<PropertyDTO> getByMappingIdAndCountryId(String mappingId, Integer setId, Integer countryId) {
|
||||
String query = """
|
||||
SELECT type.name as name,
|
||||
type.data_type as dataType,
|
||||
type.external_mapping_id as externalMappingId,
|
||||
type.validation_rule as validationRule,
|
||||
type.is_required as is_required,
|
||||
type.description as description,
|
||||
type.property_group as propertyGroup,
|
||||
type.sequence_number as sequenceNumber,
|
||||
valid.property_value as validValue
|
||||
|
||||
FROM country_property_type AS type
|
||||
LEFT JOIN (
|
||||
SELECT cp.property_value, cp.country_property_type_id
|
||||
FROM country_property cp
|
||||
JOIN property_set ps ON ps.id = cp.property_set_id
|
||||
WHERE cp.country_id = ? AND ps.id = ?
|
||||
) AS valid ON valid.country_property_type_id = type.id
|
||||
WHERE type.external_mapping_id = ?
|
||||
""";
|
||||
|
||||
var property = jdbcTemplate.query(query, new PropertyMapper(), countryId, countryId, setId, mappingId);
|
||||
|
||||
if (property.isEmpty())
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(property.getFirst());
|
||||
}
|
||||
|
||||
private Integer getTypeIdByMappingId(String mappingId) {
|
||||
String query = "SELECT id FROM country_property_type WHERE external_mapping_id = ?";
|
||||
return jdbcTemplate.queryForObject(query, Integer.class, mappingId);
|
||||
|
|
|
|||
|
|
@ -146,6 +146,25 @@ public class PropertyRepository {
|
|||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<PropertyDTO> getPropertyByMappingId(SystemPropertyMappingId mappingId, Integer setId) {
|
||||
String query = """
|
||||
SELECT type.name as name, type.data_type as dataType, type.external_mapping_id as externalMappingId, type.validation_rule as validationRule,
|
||||
type.description as description, type.property_group as propertyGroup, type.sequence_number as sequenceNumber,
|
||||
property.property_value as draftValue, property.property_value as validValue
|
||||
FROM system_property_type AS type
|
||||
LEFT JOIN system_property AS property ON property.system_property_type_id = type.id
|
||||
LEFT JOIN property_set AS propertySet ON propertySet.id = property.property_set_id
|
||||
WHERE propertySet.id = ? AND type.external_mapping_id = ?
|
||||
""";
|
||||
|
||||
var property = jdbcTemplate.query(query, new PropertyMapper(), setId, mappingId.name());
|
||||
|
||||
if (property.isEmpty()) return Optional.empty();
|
||||
else return Optional.of(property.getFirst());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the draft property set with values from a valid property set.
|
||||
* This method ensures that the draft set contains all properties with their latest valid values.
|
||||
|
|
|
|||
|
|
@ -171,12 +171,39 @@ public class ContainerRateRepository {
|
|||
return jdbcTemplate.query(query, new ContainerRateMapper(true), ValidityPeriodState.VALID.name(), mainRun.getToNodeId(), TransportType.POST_RUN.name());
|
||||
}
|
||||
|
||||
public Optional<ContainerRate> findRoute(Integer fromNodeId, Integer toNodeId, TransportType type) {
|
||||
|
||||
@Transactional
|
||||
public Optional<ContainerRate> findRoute(Integer fromNodeId, Integer toNodeId, Integer periodId, TransportType type) {
|
||||
String query = """
|
||||
SELECT * FROM container_rate WHERE from_node_id = ? AND to_node_id = ? AND container_rate_type = ?
|
||||
SELECT * FROM container_rate WHERE from_node_id = ? AND to_node_id = ? AND container_rate_type = ? AND validity_period_id = ?
|
||||
""";
|
||||
|
||||
var route = jdbcTemplate.query(query, new ContainerRateMapper(), fromNodeId, toNodeId, type.name());
|
||||
var route = jdbcTemplate.query(query, new ContainerRateMapper(), fromNodeId, toNodeId, type.name(), periodId);
|
||||
|
||||
if(route.isEmpty())
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(route.getFirst());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<ContainerRate> findRoute(Integer fromNodeId, Integer toNodeId, TransportType type) {
|
||||
|
||||
String query = """
|
||||
SELECT cr.id AS id,
|
||||
cr.validity_period_id AS validity_period_id,
|
||||
cr.container_rate_type AS container_rate_type,
|
||||
cr.from_node_id AS from_node_id,
|
||||
cr.to_node_id AS to_node_id,
|
||||
cr.rate_feu AS rate_feu,
|
||||
cr.rate_teu AS rate_teu,
|
||||
cr.rate_hc AS rate_hc,
|
||||
cr.lead_time AS lead_time
|
||||
FROM container_rate AS cr LEFT JOIN validity_period AS vp ON cr.validity_period_id = vp.id
|
||||
WHERE cr.from_node_id = ? AND cr.to_node_id = ? AND cr.container_rate_type = ? AND vp.state = ?
|
||||
""";
|
||||
|
||||
var route = jdbcTemplate.query(query, new ContainerRateMapper(), fromNodeId, toNodeId, type.name(), ValidityPeriodState.VALID.name());
|
||||
|
||||
if(route.isEmpty())
|
||||
return Optional.empty();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package de.avatic.lcc.repositories.rates;
|
||||
|
||||
import de.avatic.lcc.model.rates.MatrixRate;
|
||||
import de.avatic.lcc.model.rates.ValidityPeriodState;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
|
@ -125,8 +126,35 @@ public class MatrixRateRepository {
|
|||
|
||||
@Transactional
|
||||
public Optional<MatrixRate> getByCountryIds(Integer fromCountryId, Integer toCountryId) {
|
||||
String query = "SELECT * FROM country_matrix_rate WHERE from_country_id = ? AND to_country_id = ?";
|
||||
var rates = jdbcTemplate.query(query, new MatrixRateMapper(), fromCountryId, toCountryId);
|
||||
|
||||
String query = """
|
||||
SELECT cmr.id AS id,
|
||||
cmr.rate AS rate,
|
||||
cmr.from_country_id AS from_country_id,
|
||||
cmr.to_country_id AS to_country_id,
|
||||
cmr.validity_period_id AS validity_period_id
|
||||
FROM country_matrix_rate AS cmr LEFT JOIN validity_period AS vp ON vp.id = cmr.validity_period_id
|
||||
WHERE cmr.from_country_id = ? AND cmr.to_country_id = ? AND vp.state = ?
|
||||
""";
|
||||
|
||||
var rates = jdbcTemplate.query(query, new MatrixRateMapper(), fromCountryId, toCountryId, ValidityPeriodState.VALID.name());
|
||||
|
||||
if(rates.isEmpty())
|
||||
return Optional.empty();
|
||||
else
|
||||
return Optional.of(rates.getFirst());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<MatrixRate> getByCountryIds(Integer fromCountryId, Integer toCountryId, Integer periodId) {
|
||||
|
||||
String query = """
|
||||
SELECT *
|
||||
FROM country_matrix_rate
|
||||
WHERE from_country_id = ? AND to_country_id = ? AND validity_period_id = ?
|
||||
""";
|
||||
|
||||
var rates = jdbcTemplate.query(query, new MatrixRateMapper(), fromCountryId, toCountryId, periodId);
|
||||
|
||||
if(rates.isEmpty())
|
||||
return Optional.empty();
|
||||
|
|
|
|||
|
|
@ -100,14 +100,13 @@ public class PremisesService {
|
|||
public void startCalculation(List<Integer> premises) {
|
||||
|
||||
var userId = authorizationService.getUserId();
|
||||
|
||||
// todo check if user is allowed to schedule this
|
||||
|
||||
premises.forEach(preCalculationCheckService::doPrecheck);
|
||||
premiseRepository.checkOwner(premises, userId);
|
||||
|
||||
var validSetId = propertySetRepository.getValidSetId();
|
||||
var validPeriodId = validityPeriodRepository.getValidPeriodId().orElseThrow(() -> new InternalErrorException("no valid period found that is VALID"));
|
||||
|
||||
premises.forEach(premiseId -> preCalculationCheckService.doPrecheck(premiseId, validSetId, validPeriodId));
|
||||
|
||||
var calculationIds = new ArrayList<Integer>();
|
||||
|
||||
premises.forEach(p -> {
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public class CalculationExecutionService {
|
|||
BigDecimal fcaFee;
|
||||
|
||||
if (premise.getFcaEnabled()) {
|
||||
var fcaProperty = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FCA_FEE).orElseThrow();
|
||||
var fcaProperty = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FCA_FEE, calculation.getPropertySetId()).orElseThrow();
|
||||
var fcaShare = Double.parseDouble(fcaProperty.getCurrentValue());
|
||||
fcaFee = BigDecimal.valueOf(fcaShare).multiply(materialCost);
|
||||
} else {
|
||||
|
|
@ -110,19 +110,19 @@ public class CalculationExecutionService {
|
|||
}
|
||||
|
||||
List<Destination> destinations = destinationRepository.getByPremiseId(premise.getId());
|
||||
return destinations.stream().map(destination -> doDestinationCalculation(destination, premise, materialCost, fcaFee)).toList();
|
||||
return destinations.stream().map(destination -> doDestinationCalculation(calculation.getPropertySetId(), calculation.getValidityPeriodId(), destination, premise, materialCost, fcaFee)).toList();
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Calculation job is not scheduled");
|
||||
}
|
||||
|
||||
private DestinationInfo doDestinationCalculation(Destination destination, Premise premise, BigDecimal materialCost, BigDecimal fcaFee) {
|
||||
private DestinationInfo doDestinationCalculation(Integer setId, Integer periodId, Destination destination, Premise premise, BigDecimal materialCost, BigDecimal fcaFee) {
|
||||
|
||||
InventoryCostResult inventoryCost;
|
||||
HandlingResult handlingCost;
|
||||
CustomResult customCost;
|
||||
List<SectionInfo> sections;
|
||||
AirfreightResult airfreightCost = airfreightCalculationService.doCalculation(premise, destination);
|
||||
AirfreightResult airfreightCost = airfreightCalculationService.doCalculation(setId, periodId, premise, destination);
|
||||
ContainerType usedContainerType = null;
|
||||
|
||||
CalculationJobDestination destinationCalculationJob = new CalculationJobDestination();
|
||||
|
|
@ -130,12 +130,12 @@ public class CalculationExecutionService {
|
|||
BigDecimal leadTime = null;
|
||||
|
||||
if (destination.getD2d()) {
|
||||
var containerCalculation = containerCalculationService.doCalculation(premiseToHuService.createHuFromPremise(premise), ContainerType.FEU);
|
||||
sections = List.of(new SectionInfo(null, routeSectionCostCalculationService.doD2dCalculation(premise, destination, containerCalculation), containerCalculation));
|
||||
var containerCalculation = containerCalculationService.doCalculation(setId, premiseToHuService.createHuFromPremise(premise), ContainerType.FEU);
|
||||
sections = List.of(new SectionInfo(null, routeSectionCostCalculationService.doD2dCalculation(setId, periodId, premise, destination, containerCalculation), containerCalculation));
|
||||
leadTime = BigDecimal.valueOf(destination.getLeadTimeD2d());
|
||||
usedContainerType = ContainerType.FEU;
|
||||
} else {
|
||||
var bestContainerTypeResult = getSectionsFromBestContainerType(destination, premise);
|
||||
var bestContainerTypeResult = getSectionsFromBestContainerType(setId, periodId, destination, premise);
|
||||
sections = bestContainerTypeResult.sections;
|
||||
usedContainerType = bestContainerTypeResult.containerType;
|
||||
hasMainRun = sections.stream().anyMatch(s -> s.section().getMainRun());
|
||||
|
|
@ -156,9 +156,9 @@ public class CalculationExecutionService {
|
|||
if(destination.getD2d())
|
||||
destinationCalculationJob.setRateD2D(destination.getRateD2d());
|
||||
|
||||
customCost = customCostCalculationService.doCalculation(premise, destination, sections);
|
||||
handlingCost = handlingCostCalculationService.doCalculation(premise, destination, hasMainRun);
|
||||
inventoryCost = inventoryCostCalculationService.doCalculation(premise, destination, leadTime);
|
||||
customCost = customCostCalculationService.doCalculation(setId, premise, destination, sections);
|
||||
handlingCost = handlingCostCalculationService.doCalculation(setId, premise, destination, hasMainRun);
|
||||
inventoryCost = inventoryCostCalculationService.doCalculation(setId, premise, destination, leadTime);
|
||||
|
||||
destinationCalculationJob.setContainerType(usedContainerType);
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ public class CalculationExecutionService {
|
|||
destinationCalculationJob.setHuCount(sections.getFirst().containerResult().getHuUnitCount());
|
||||
|
||||
destinationCalculationJob.setAnnualAmount(BigDecimal.valueOf(destination.getAnnualAmount()));
|
||||
destinationCalculationJob.setShippingFrequency(shippingFrequencyCalculationService.doCalculation(destination.getAnnualAmount()));
|
||||
destinationCalculationJob.setShippingFrequency(shippingFrequencyCalculationService.doCalculation(setId, destination.getAnnualAmount()));
|
||||
|
||||
var commonCost = destinationCalculationJob.getAnnualHandlingCost()
|
||||
.add(destinationCalculationJob.getAnnualDisposalCost())
|
||||
|
|
@ -223,7 +223,7 @@ public class CalculationExecutionService {
|
|||
return new DestinationInfo(destination, destinationCalculationJob, sections);
|
||||
}
|
||||
|
||||
private BestContainerTypeResult getSectionsFromBestContainerType(Destination destination, Premise premise) {
|
||||
private BestContainerTypeResult getSectionsFromBestContainerType(Integer setId, Integer periodId, Destination destination, Premise premise) {
|
||||
PackagingDimension hu = premiseToHuService.createHuFromPremise(premise);
|
||||
|
||||
var route = routeRepository.getSelectedByDestinationId(destination.getId()).orElseThrow();
|
||||
|
|
@ -234,7 +234,7 @@ public class CalculationExecutionService {
|
|||
|
||||
// Get container calculation
|
||||
for (var containerType : ContainerType.values()) {
|
||||
containerCalculation.put(containerType, containerCalculationService.doCalculation(hu, containerType));
|
||||
containerCalculation.put(containerType, containerCalculationService.doCalculation(setId, hu, containerType));
|
||||
}
|
||||
|
||||
for (var containerType : ContainerType.values()) {
|
||||
|
|
@ -244,7 +244,7 @@ public class CalculationExecutionService {
|
|||
|
||||
for (var section : routeSections) {
|
||||
var container = RateType.MATRIX == section.getRateType() ? containerCalculation.get(ContainerType.TRUCK) : containerCalculation.get(containerType);
|
||||
sectionInfo.add(new SectionInfo(section, routeSectionCostCalculationService.doCalculation(premise, destination, section, container), containerCalculation.get(containerType)));
|
||||
sectionInfo.add(new SectionInfo(section, routeSectionCostCalculationService.doCalculation(setId, periodId, premise, destination, section, container), containerCalculation.get(containerType)));
|
||||
}
|
||||
|
||||
sectionInfos.put(containerType, sectionInfo);
|
||||
|
|
|
|||
|
|
@ -28,21 +28,21 @@ public class AirfreightCalculationService {
|
|||
this.countryPropertyRepository = countryPropertyRepository;
|
||||
}
|
||||
|
||||
public AirfreightResult doCalculation(Premise premise, Destination destination) {
|
||||
public AirfreightResult doCalculation(Integer setId, Integer periodId, Premise premise, Destination destination) {
|
||||
|
||||
var maxAirfreightShare = Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.AIR_SHARE, premise.getCountryId()).orElseThrow().getCurrentValue());
|
||||
var maxAirfreightShare = Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.AIR_SHARE, setId, premise.getCountryId()).orElseThrow().getCurrentValue());
|
||||
var overseaShare = premise.getOverseaShare().doubleValue();
|
||||
var airfreightShare = getAirfreightShare(maxAirfreightShare, overseaShare);
|
||||
|
||||
var hu = premiseToHuService.createHuFromPremise(premise);
|
||||
|
||||
var preCarriage = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_PRECARRIAGE).orElseThrow().getCurrentValue()));
|
||||
var mainCarriage = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_MAINCARRIAGE).orElseThrow().getCurrentValue()));
|
||||
var postCarriage = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_ONCARRIAGE).orElseThrow().getCurrentValue()));
|
||||
var terminalFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_TERMINAL_FEE).orElseThrow().getCurrentValue()));
|
||||
var preCarriageFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_HANDLING).orElseThrow().getCurrentValue()));
|
||||
var customsClearanceFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_CUSTOM_FEE).orElseThrow().getCurrentValue()));
|
||||
var handOverFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_HANDOVER_FEE).orElseThrow().getCurrentValue()));
|
||||
var preCarriage = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_PRECARRIAGE, setId).orElseThrow().getCurrentValue()));
|
||||
var mainCarriage = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_MAINCARRIAGE, setId).orElseThrow().getCurrentValue()));
|
||||
var postCarriage = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_ONCARRIAGE, setId).orElseThrow().getCurrentValue()));
|
||||
var terminalFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_TERMINAL_FEE, setId).orElseThrow().getCurrentValue()));
|
||||
var preCarriageFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_HANDLING, setId).orElseThrow().getCurrentValue()));
|
||||
var customsClearanceFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_CUSTOM_FEE, setId).orElseThrow().getCurrentValue()));
|
||||
var handOverFee = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_HANDOVER_FEE, setId).orElseThrow().getCurrentValue()));
|
||||
|
||||
var result = new AirfreightResult();
|
||||
|
||||
|
|
@ -69,11 +69,11 @@ public class AirfreightCalculationService {
|
|||
}
|
||||
|
||||
private double getDimensionInCm(Number dimension, DimensionUnit unit) {
|
||||
return DimensionUnit.CM.convertFromMM(dimension).doubleValue();
|
||||
return DimensionUnit.CM.convertFromMM(dimension);
|
||||
}
|
||||
|
||||
private double getWeightInKg(PackagingDimension hu) {
|
||||
return WeightUnit.KG.convertFromG(hu.getWeight()).doubleValue();
|
||||
return WeightUnit.KG.convertFromG(hu.getWeight());
|
||||
}
|
||||
|
||||
private double getAirfreightShare(double maxAirfreightShare, double overseaShare) {
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ public class ChangeRiskFactorCalculationService {
|
|||
this.nodeRepository = nodeRepository;
|
||||
}
|
||||
|
||||
public ChangeRiskFactorCalculationResult getChanceRiskFactors() {
|
||||
var rate = findRate();
|
||||
var riskValue = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.RISK_REF).orElseThrow().getCurrentValue()));
|
||||
var chanceValue = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CHANCE_REF).orElseThrow().getCurrentValue()));
|
||||
public ChangeRiskFactorCalculationResult getChanceRiskFactors(Integer setId, Integer periodId) {
|
||||
var rate = findRate(setId, periodId);
|
||||
var riskValue = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.RISK_REF, setId).orElseThrow().getCurrentValue()));
|
||||
var chanceValue = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CHANCE_REF, setId).orElseThrow().getCurrentValue()));
|
||||
|
||||
var result = new ChangeRiskFactorCalculationResult();
|
||||
result.setChanceFactor(chanceValue.divide(rate.getRateFeu(), 2, RoundingMode.HALF_UP));
|
||||
|
|
@ -36,14 +36,14 @@ public class ChangeRiskFactorCalculationService {
|
|||
return result;
|
||||
}
|
||||
|
||||
private ContainerRate findRate() {
|
||||
var startReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.START_REF).orElseThrow().getCurrentValue();
|
||||
var endReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.END_REF).orElseThrow().getCurrentValue();
|
||||
private ContainerRate findRate(Integer setId, Integer periodId) {
|
||||
var startReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.START_REF, setId).orElseThrow().getCurrentValue();
|
||||
var endReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.END_REF, setId).orElseThrow().getCurrentValue();
|
||||
|
||||
var startNode = nodeRepository.getByExternalMappingId(startReference).orElseThrow();
|
||||
var endNode = nodeRepository.getByExternalMappingId(endReference).orElseThrow();
|
||||
|
||||
return containerRateRepository.findRoute(startNode.getId(), endNode.getId(), TransportType.SEA).orElseThrow();
|
||||
return containerRateRepository.findRoute(startNode.getId(), endNode.getId(), periodId, TransportType.SEA).orElseThrow();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@ public class ContainerCalculationService {
|
|||
* @param containerType The type of container to be loaded
|
||||
* @return ContainerCalculationResult containing loading pattern and capacity information
|
||||
*/
|
||||
public ContainerCalculationResult doCalculation(PackagingDimension hu, ContainerType containerType) {
|
||||
public ContainerCalculationResult doCalculation(Integer setId, PackagingDimension hu, ContainerType containerType) {
|
||||
|
||||
var weightInKg = BigDecimal.valueOf(WeightUnit.KG.convertFromG(hu.getWeight()));
|
||||
var maxContainerLoad = BigDecimal.valueOf(getMaxContainerLoad(containerType));
|
||||
var maxContainerLoad = BigDecimal.valueOf(getMaxContainerLoad(containerType, setId));
|
||||
var maxUnitByWeight = maxContainerLoad.divide(weightInKg, 0, RoundingMode.HALF_UP).intValueExact();
|
||||
|
||||
var dimensions = hu.withTolerance(DIMENSION_TOLERANCE);
|
||||
|
|
@ -144,7 +144,7 @@ public class ContainerCalculationService {
|
|||
* @throws IllegalArgumentException if container type is not supported
|
||||
* @throws IllegalStateException if required property is missing
|
||||
*/
|
||||
private int getMaxContainerLoad(ContainerType containerType) {
|
||||
private int getMaxContainerLoad(ContainerType containerType, Integer setId) {
|
||||
Map<ContainerType, SystemPropertyMappingId> mappings = Map.of(
|
||||
ContainerType.FEU, SystemPropertyMappingId.FEU_LOAD,
|
||||
ContainerType.TRUCK, SystemPropertyMappingId.TRUCK_LOAD,
|
||||
|
|
@ -157,7 +157,7 @@ public class ContainerCalculationService {
|
|||
throw new IllegalArgumentException("Unsupported container type: " + containerType);
|
||||
}
|
||||
|
||||
var value = propertyRepository.getPropertyByMappingId(mappingId)
|
||||
var value = propertyRepository.getPropertyByMappingId(mappingId, setId)
|
||||
.orElseThrow(() -> new IllegalStateException("Missing property: " + mappingId))
|
||||
.getCurrentValue();
|
||||
|
||||
|
|
|
|||
|
|
@ -48,14 +48,14 @@ public class CustomCostCalculationService {
|
|||
}
|
||||
}
|
||||
|
||||
public CustomResult doCalculation(Premise premise, Destination destination, List<SectionInfo> sections) {
|
||||
public CustomResult doCalculation(Integer setId, Premise premise, Destination destination, List<SectionInfo> sections) {
|
||||
|
||||
var destUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, destination.getCountryId()).orElseThrow();
|
||||
var sourceUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, premise.getCountryId()).orElseThrow();
|
||||
var destUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, setId, destination.getCountryId()).orElseThrow();
|
||||
var sourceUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, setId, premise.getCountryId()).orElseThrow();
|
||||
|
||||
if (CustomUnionType.EU.name().equals(destUnion.getCurrentValue()) && (sourceUnion.getCurrentValue() == null || CustomUnionType.NONE.name().equals(sourceUnion.getCurrentValue()))) {
|
||||
|
||||
var relevantSections = getCustomRelevantRouteSections(sections);
|
||||
var relevantSections = getCustomRelevantRouteSections(setId, sections);
|
||||
|
||||
var transportationCost = relevantSections.stream().map(s -> s.result().getAnnualCost()).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
var transportationChanceCost = relevantSections.stream().map(s -> s.result().getAnnualChanceCost()).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
|
@ -64,15 +64,15 @@ public class CustomCostCalculationService {
|
|||
|
||||
double huAnnualAmount = BigDecimal.valueOf(destination.getAnnualAmount()).divide(BigDecimal.valueOf(relevantSections.getFirst().containerResult().getHuUnitCount()),2, RoundingMode.HALF_UP).doubleValue();
|
||||
|
||||
return getCustomCalculationResult(premise, destination, getContainerShare(premise, relevantSections.getFirst().containerResult()), huAnnualAmount, transportationCost, transportationChanceCost, transportationRiskCost);
|
||||
return getCustomCalculationResult(setId, premise, destination, getContainerShare(premise, relevantSections.getFirst().containerResult()), huAnnualAmount, transportationCost, transportationChanceCost, transportationRiskCost);
|
||||
}
|
||||
|
||||
return CustomResult.EMPTY;
|
||||
}
|
||||
|
||||
private CustomResult getCustomCalculationResult(Premise premise, Destination destination, BigDecimal containerShare, double huAnnualAmount, BigDecimal transportationCost, BigDecimal transportationChanceCost, BigDecimal transportationRiskCost) {
|
||||
var shippingFrequency = shippingFrequencyCalculationService.doCalculation(huAnnualAmount);
|
||||
var customFee = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CUSTOM_FEE).orElseThrow().getCurrentValue());
|
||||
private CustomResult getCustomCalculationResult(Integer setId, Premise premise, Destination destination, BigDecimal containerShare, double huAnnualAmount, BigDecimal transportationCost, BigDecimal transportationChanceCost, BigDecimal transportationRiskCost) {
|
||||
var shippingFrequency = shippingFrequencyCalculationService.doCalculation(setId, huAnnualAmount);
|
||||
var customFee = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CUSTOM_FEE, setId).orElseThrow().getCurrentValue());
|
||||
|
||||
var tariffRate = premise.getTariffRate() == null ? customApiService.getTariffRate(premise.getHsCode(), premise.getCountryId()) : premise.getTariffRate();
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ public class CustomCostCalculationService {
|
|||
var fcaFee = BigDecimal.ZERO;
|
||||
|
||||
if (premise.getFcaEnabled()) {
|
||||
var fcaProperty = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FCA_FEE).orElseThrow();
|
||||
var fcaProperty = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FCA_FEE, setId).orElseThrow();
|
||||
var fcaShare = Double.parseDouble(fcaProperty.getCurrentValue());
|
||||
fcaFee = BigDecimal.valueOf(fcaShare).multiply(materialCost);
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ public class CustomCostCalculationService {
|
|||
return new CustomResult(customValue, customRiskValue, customChanceValue, customDuties, tariffRate, annualCost, annualRiskCost, annualChanceCost);
|
||||
}
|
||||
|
||||
private List<SectionInfo> getCustomRelevantRouteSections(List<SectionInfo> sections) {
|
||||
private List<SectionInfo> getCustomRelevantRouteSections(Integer setId, List<SectionInfo> sections) {
|
||||
|
||||
List<SectionInfo> customSections = new ArrayList<>();
|
||||
|
||||
|
|
@ -111,8 +111,8 @@ public class CustomCostCalculationService {
|
|||
}
|
||||
|
||||
for (SectionInfo section : sections) {
|
||||
if (!(CustomUnionType.EU == getCustomUnionByRouteNodeId(section.section().getFromRouteNodeId()) &&
|
||||
CustomUnionType.EU == getCustomUnionByRouteNodeId(section.section().getToRouteNodeId()))) {
|
||||
if (!(CustomUnionType.EU == getCustomUnionByRouteNodeId(setId, section.section().getFromRouteNodeId()) &&
|
||||
CustomUnionType.EU == getCustomUnionByRouteNodeId(setId, section.section().getToRouteNodeId()))) {
|
||||
customSections.add(section);
|
||||
}
|
||||
}
|
||||
|
|
@ -120,13 +120,13 @@ public class CustomCostCalculationService {
|
|||
return customSections;
|
||||
}
|
||||
|
||||
private CustomUnionType getCustomUnionByRouteNodeId(Integer routeNodeId) {
|
||||
private CustomUnionType getCustomUnionByRouteNodeId(Integer setId, Integer routeNodeId) {
|
||||
var node = routeNodeRepository.getById(routeNodeId).orElseThrow();
|
||||
return getCustomUnionByCountryId(node.getCountryId());
|
||||
return getCustomUnionByCountryId(setId, node.getCountryId());
|
||||
}
|
||||
|
||||
private CustomUnionType getCustomUnionByCountryId(Integer countryId) {
|
||||
var property = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, countryId).orElseThrow();
|
||||
private CustomUnionType getCustomUnionByCountryId(Integer setId, Integer countryId) {
|
||||
var property = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, setId, countryId).orElseThrow();
|
||||
if (property.getCurrentValue() == null)
|
||||
return CustomUnionType.NONE;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,36 +30,36 @@ public class HandlingCostCalculationService {
|
|||
this.shippingFrequencyCalculationService = shippingFrequencyCalculationService;
|
||||
}
|
||||
|
||||
public HandlingResult doCalculation(Premise premise, Destination destination, Boolean addRepackingCosts) {
|
||||
public HandlingResult doCalculation(Integer setId, Premise premise, Destination destination, Boolean addRepackingCosts) {
|
||||
|
||||
var hu = premiseToHuService.createHuFromPremise(premise);
|
||||
return (LoadCarrierType.SLC == hu.getLoadCarrierType() ? getSLCCost(destination, hu, hu.getLoadCarrierType(), addRepackingCosts) : getLLCCost(destination, hu, hu.getLoadCarrierType(), addRepackingCosts));
|
||||
return (LoadCarrierType.SLC == hu.getLoadCarrierType() ? getSLCCost(setId, destination, hu, hu.getLoadCarrierType(), addRepackingCosts) : getLLCCost(setId, destination, hu, hu.getLoadCarrierType(), addRepackingCosts));
|
||||
}
|
||||
|
||||
private HandlingResult getSLCCost(Destination destination, PackagingDimension hu, LoadCarrierType loadCarrierType, boolean addRepackingCosts) {
|
||||
private HandlingResult getSLCCost(Integer setId, Destination destination, PackagingDimension hu, LoadCarrierType loadCarrierType, boolean addRepackingCosts) {
|
||||
|
||||
var destinationHandling = destination.getHandlingCost();
|
||||
var destinationDisposal = destination.getDisposalCost();
|
||||
var destinationRepacking = destination.getRepackingCost();
|
||||
|
||||
BigDecimal huAnnualAmount = BigDecimal.valueOf(destination.getAnnualAmount()).divide(BigDecimal.valueOf(hu.getContentUnitCount()),4, RoundingMode.UP );
|
||||
BigDecimal handling = destinationHandling != null ? destinationHandling : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_HANDLING).orElseThrow().getCurrentValue()));
|
||||
BigDecimal release = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_RELEASE).orElseThrow().getCurrentValue()));
|
||||
BigDecimal dispatch = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_DISPATCH).orElseThrow().getCurrentValue()));
|
||||
BigDecimal disposal = destinationDisposal != null ? destinationDisposal : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.DISPOSAL).orElseThrow().getCurrentValue()));
|
||||
BigDecimal handling = destinationHandling != null ? destinationHandling : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_HANDLING, setId).orElseThrow().getCurrentValue()));
|
||||
BigDecimal release = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_RELEASE, setId).orElseThrow().getCurrentValue()));
|
||||
BigDecimal dispatch = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_DISPATCH, setId).orElseThrow().getCurrentValue()));
|
||||
BigDecimal disposal = destinationDisposal != null ? destinationDisposal : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.DISPOSAL, setId).orElseThrow().getCurrentValue()));
|
||||
|
||||
BigDecimal wageFactor = BigDecimal.valueOf(Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.WAGE, destination.getCountryId()).orElseThrow().getCurrentValue()));
|
||||
BigDecimal booking = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING_KLT).orElseThrow().getCurrentValue()));
|
||||
BigDecimal wageFactor = BigDecimal.valueOf(Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.WAGE, setId, destination.getCountryId()).orElseThrow().getCurrentValue()));
|
||||
BigDecimal booking = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING_KLT, setId).orElseThrow().getCurrentValue()));
|
||||
|
||||
return new HandlingResult(LoadCarrierType.SLC,
|
||||
getRepackingCost(hu, loadCarrierType, addRepackingCosts, destinationRepacking).multiply(huAnnualAmount),
|
||||
getRepackingCost(setId, hu, loadCarrierType, addRepackingCosts, destinationRepacking).multiply(huAnnualAmount),
|
||||
handling.multiply(huAnnualAmount),
|
||||
destinationDisposal == null ? BigDecimal.ZERO : (disposal.multiply(huAnnualAmount)), //TODO: disposal SLC, ignore?
|
||||
huAnnualAmount.multiply((handling.add(booking).add(release).add(dispatch).add(getRepackingCost(hu, loadCarrierType, addRepackingCosts, destinationRepacking)))).multiply(wageFactor));
|
||||
huAnnualAmount.multiply((handling.add(booking).add(release).add(dispatch).add(getRepackingCost(setId, hu, loadCarrierType, addRepackingCosts, destinationRepacking)))).multiply(wageFactor));
|
||||
|
||||
}
|
||||
|
||||
private BigDecimal getRepackingCost(PackagingDimension hu, LoadCarrierType type, boolean addRepackingCosts, BigDecimal userInput) {
|
||||
private BigDecimal getRepackingCost(Integer setId, PackagingDimension hu, LoadCarrierType type, boolean addRepackingCosts, BigDecimal userInput) {
|
||||
|
||||
if(userInput != null)
|
||||
return userInput;
|
||||
|
|
@ -70,30 +70,30 @@ public class HandlingCostCalculationService {
|
|||
|
||||
return switch (type) {
|
||||
case SLC ->
|
||||
BigDecimal.valueOf(Double.parseDouble((hu.getWeight() < 15_000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_REPACK_S).orElseThrow().getCurrentValue() : propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_REPACK_M).orElseThrow().getCurrentValue()));
|
||||
BigDecimal.valueOf(Double.parseDouble((hu.getWeight() < 15_000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_REPACK_S, setId).orElseThrow().getCurrentValue() : propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_REPACK_M, setId).orElseThrow().getCurrentValue()));
|
||||
case LLC ->
|
||||
BigDecimal.valueOf(Double.parseDouble(((hu.getWeight() < 15_000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_S) : (hu.getWeight() < 2_000_000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_M) : propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_L)).orElseThrow().getCurrentValue()));
|
||||
BigDecimal.valueOf(Double.parseDouble(((hu.getWeight() < 15_000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_S, setId) : (hu.getWeight() < 2_000_000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_M, setId) : propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_L, setId)).orElseThrow().getCurrentValue()));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private HandlingResult getLLCCost(Destination destination, PackagingDimension hu, LoadCarrierType type, boolean addRepackingCosts) {
|
||||
private HandlingResult getLLCCost(Integer setId, Destination destination, PackagingDimension hu, LoadCarrierType type, boolean addRepackingCosts) {
|
||||
|
||||
var destinationHandling = destination.getHandlingCost();
|
||||
var destinationDisposal = destination.getDisposalCost();
|
||||
var destinationRepacking = destination.getRepackingCost();
|
||||
|
||||
BigDecimal huAnnualAmount = BigDecimal.valueOf(destination.getAnnualAmount()).divide(BigDecimal.valueOf(hu.getContentUnitCount()),4, RoundingMode.UP );
|
||||
BigDecimal handling = destinationHandling != null ? destinationHandling : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_HANDLING).orElseThrow().getCurrentValue()));
|
||||
BigDecimal release = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_RELEASE).orElseThrow().getCurrentValue()));
|
||||
BigDecimal dispatch = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_DISPATCH).orElseThrow().getCurrentValue()));
|
||||
BigDecimal disposal = destinationDisposal != null ? destinationDisposal : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.DISPOSAL).orElseThrow().getCurrentValue()));
|
||||
BigDecimal handling = destinationHandling != null ? destinationHandling : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_HANDLING, setId).orElseThrow().getCurrentValue()));
|
||||
BigDecimal release = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_RELEASE, setId).orElseThrow().getCurrentValue()));
|
||||
BigDecimal dispatch = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_DISPATCH, setId).orElseThrow().getCurrentValue()));
|
||||
BigDecimal disposal = destinationDisposal != null ? destinationDisposal : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.DISPOSAL, setId).orElseThrow().getCurrentValue()));
|
||||
|
||||
BigDecimal wageFactor = BigDecimal.valueOf(Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.WAGE, destination.getCountryId()).orElseThrow().getCurrentValue()));
|
||||
BigDecimal booking = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING).orElseThrow().getCurrentValue()));
|
||||
BigDecimal wageFactor = BigDecimal.valueOf(Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.WAGE, setId, destination.getCountryId()).orElseThrow().getCurrentValue()));
|
||||
BigDecimal booking = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING, setId).orElseThrow().getCurrentValue()));
|
||||
|
||||
var annualRepacking = getRepackingCost(hu, type, addRepackingCosts, destinationRepacking).multiply(wageFactor).multiply( huAnnualAmount);
|
||||
var annualHandling = ((handling.add(dispatch).add(release)).multiply(wageFactor).multiply(huAnnualAmount)).add(booking.multiply(BigDecimal.valueOf(shippingFrequencyCalculationService.doCalculation(huAnnualAmount.doubleValue()))));
|
||||
var annualRepacking = getRepackingCost(setId, hu, type, addRepackingCosts, destinationRepacking).multiply(wageFactor).multiply( huAnnualAmount);
|
||||
var annualHandling = ((handling.add(dispatch).add(release)).multiply(wageFactor).multiply(huAnnualAmount)).add(booking.multiply(BigDecimal.valueOf(shippingFrequencyCalculationService.doCalculation(setId, huAnnualAmount.doubleValue()))));
|
||||
var annualDisposal = (disposal.multiply(huAnnualAmount));
|
||||
|
||||
return new HandlingResult(LoadCarrierType.LLC, annualRepacking, annualHandling, annualDisposal, annualRepacking.add(annualHandling).add(annualDisposal));
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class InventoryCostCalculationService {
|
|||
this.premiseToHuService = premiseToHuService;
|
||||
}
|
||||
|
||||
public InventoryCostResult doCalculation(Premise premise, Destination destination, BigDecimal leadTime) {
|
||||
public InventoryCostResult doCalculation(Integer setId, Premise premise, Destination destination, BigDecimal leadTime) {
|
||||
|
||||
|
||||
var fcaFee = BigDecimal.ZERO;
|
||||
|
|
@ -44,16 +44,16 @@ public class InventoryCostCalculationService {
|
|||
var hu = premiseToHuService.createHuFromPremise(premise);
|
||||
double huAnnualAmount = BigDecimal.valueOf(destination.getAnnualAmount()).divide(BigDecimal.valueOf(hu.getContentUnitCount()),0, RoundingMode.UP ).doubleValue();
|
||||
|
||||
var safetyDays = BigDecimal.valueOf(Integer.parseInt(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.SAFETY_STOCK, premise.getCountryId()).orElseThrow().getCurrentValue()));
|
||||
var workdays = BigDecimal.valueOf(Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.WORKDAYS).orElseThrow().getCurrentValue()));
|
||||
var paymentTerms = BigDecimal.valueOf(Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.PAYMENT_TERMS).orElseThrow().getCurrentValue()));
|
||||
var interestRate = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.INTEREST_RATE).orElseThrow().getCurrentValue()));
|
||||
var safetyDays = BigDecimal.valueOf(Integer.parseInt(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.SAFETY_STOCK, setId, premise.getCountryId()).orElseThrow().getCurrentValue()));
|
||||
var workdays = BigDecimal.valueOf(Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.WORKDAYS, setId).orElseThrow().getCurrentValue()));
|
||||
var paymentTerms = BigDecimal.valueOf(Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.PAYMENT_TERMS, setId).orElseThrow().getCurrentValue()));
|
||||
var interestRate = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.INTEREST_RATE, setId).orElseThrow().getCurrentValue()));
|
||||
|
||||
var annualAmount = BigDecimal.valueOf(destination.getAnnualAmount().doubleValue());
|
||||
var dailyAmount = annualAmount.divide(BigDecimal.valueOf(365), 10, RoundingMode.HALF_UP);
|
||||
var workdayAmount = annualAmount.divide(workdays, 10, RoundingMode.HALF_UP);
|
||||
|
||||
var opStock = (annualAmount.divide(BigDecimal.valueOf(Math.max(shippingFrequencyCalculationService.doCalculation(huAnnualAmount),1)), 10, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(.5)));
|
||||
var opStock = (annualAmount.divide(BigDecimal.valueOf(Math.max(shippingFrequencyCalculationService.doCalculation(setId, huAnnualAmount),1)), 10, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(.5)));
|
||||
var safetyStock = safetyDays.multiply(workdayAmount);
|
||||
var stockedInventory = opStock.add(safetyStock);
|
||||
var inTransportStock = dailyAmount.multiply(leadTime);
|
||||
|
|
@ -63,15 +63,15 @@ public class InventoryCostCalculationService {
|
|||
var storageCostStock = roundToHu(hu, safetyStock.add(opStock));
|
||||
|
||||
var capitalCost = capitalCostStock.multiply(interestRate).multiply(premise.getMaterialCost().add(fcaFee));
|
||||
var storageCost = storageCostStock.multiply(getSpaceCostPerHu(hu)).multiply(BigDecimal.valueOf(365));
|
||||
var storageCost = storageCostStock.multiply(getSpaceCostPerHu(setId, hu)).multiply(BigDecimal.valueOf(365));
|
||||
|
||||
|
||||
return new InventoryCostResult(opStock, safetyStock, stockedInventory, inTransportStock, stockBeforePayment, capitalCost, storageCost, safetyDays );
|
||||
|
||||
}
|
||||
|
||||
private BigDecimal getSpaceCostPerHu(PackagingDimension hu) {
|
||||
var spaceCost = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.SPACE_COST).orElseThrow().getCurrentValue()));
|
||||
private BigDecimal getSpaceCostPerHu(Integer setId, PackagingDimension hu) {
|
||||
var spaceCost = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.SPACE_COST, setId).orElseThrow().getCurrentValue()));
|
||||
var spaceCostPerHu = BigDecimal.valueOf(hu.getFloorArea(DimensionUnit.M)*hu.getRoundedHeight(DimensionUnit.M)).multiply(spaceCost);
|
||||
return spaceCostPerHu;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public class RouteSectionCostCalculationService {
|
|||
this.nodeRepository = nodeRepository;
|
||||
}
|
||||
|
||||
public CalculationJobRouteSection doD2dCalculation(Premise premise, Destination destination, ContainerCalculationResult containerCalculation) {
|
||||
public CalculationJobRouteSection doD2dCalculation(Integer setId, Integer periodId, Premise premise, Destination destination, ContainerCalculationResult containerCalculation) {
|
||||
CalculationJobRouteSection result = new CalculationJobRouteSection();
|
||||
|
||||
// Set route metadata
|
||||
|
|
@ -78,7 +78,7 @@ public class RouteSectionCostCalculationService {
|
|||
result.setTransitTime(transitTime);
|
||||
|
||||
// Calculate price and annual cost
|
||||
BigDecimal utilization = getUtilization(RateType.CONTAINER); /* D2D is always 40ft container */
|
||||
BigDecimal utilization = getUtilization(setId, RateType.CONTAINER); /* D2D is always 40ft container */
|
||||
double annualVolume = destination.getAnnualAmount() * containerCalculation.getHu().getVolume(DimensionUnit.M);
|
||||
|
||||
PriceCalculationResult prices = calculatePrices(
|
||||
|
|
@ -97,7 +97,7 @@ public class RouteSectionCostCalculationService {
|
|||
result.setWeightPrice(prices.weightPrice);
|
||||
result.setUtilization(prices.utilization);
|
||||
|
||||
var chanceRiskFactors = changeRiskFactorCalculationService.getChanceRiskFactors();
|
||||
var chanceRiskFactors = changeRiskFactorCalculationService.getChanceRiskFactors(setId, periodId);
|
||||
|
||||
BigDecimal annualCost = (containerCalculation.isWeightExceeded() ? prices.weightPrice : prices.volumePrice).multiply(BigDecimal.valueOf(annualVolume));
|
||||
BigDecimal annualRiskCost = annualCost.multiply(chanceRiskFactors.getRiskFactor());
|
||||
|
|
@ -110,7 +110,7 @@ public class RouteSectionCostCalculationService {
|
|||
return result;
|
||||
}
|
||||
|
||||
public CalculationJobRouteSection doCalculation(Premise premise, Destination destination, RouteSection section, ContainerCalculationResult containerCalculation) {
|
||||
public CalculationJobRouteSection doCalculation(Integer setId, Integer periodId, Premise premise, Destination destination, RouteSection section, ContainerCalculationResult containerCalculation) {
|
||||
CalculationJobRouteSection result = new CalculationJobRouteSection();
|
||||
|
||||
// Set route metadata
|
||||
|
|
@ -135,11 +135,11 @@ public class RouteSectionCostCalculationService {
|
|||
int transitTime;
|
||||
|
||||
if (RateType.CONTAINER == section.getRateType()) {
|
||||
ContainerRate containerRate = findContainerRate(section, fromNode, toNode);
|
||||
ContainerRate containerRate = findContainerRate(section, fromNode, toNode, periodId);
|
||||
rate = getContainerRate(containerRate, containerCalculation.getContainerType());
|
||||
transitTime = containerRate.getLeadTime();
|
||||
} else if (RateType.MATRIX == section.getRateType()) {
|
||||
MatrixRate matrixRate = findMatrixRate(fromNode, toNode);
|
||||
MatrixRate matrixRate = findMatrixRate(fromNode, toNode, periodId);
|
||||
rate = matrixRate.getRate().multiply(BigDecimal.valueOf(distance));
|
||||
transitTime = 3; // Default transit time for matrix rate
|
||||
} else if (RateType.NEAR_BY == section.getRateType()) {
|
||||
|
|
@ -154,7 +154,7 @@ public class RouteSectionCostCalculationService {
|
|||
|
||||
// Calculate price and annual cost
|
||||
BigDecimal huAnnualAmount = BigDecimal.valueOf(destination.getAnnualAmount()).divide(BigDecimal.valueOf(containerCalculation.getHu().getContentUnitCount()), 2, RoundingMode.HALF_UP);
|
||||
BigDecimal utilization = getUtilization(section.getRateType());
|
||||
BigDecimal utilization = getUtilization(setId, section.getRateType());
|
||||
BigDecimal annualVolume = huAnnualAmount.multiply(BigDecimal.valueOf(containerCalculation.getHu().getVolume(DimensionUnit.M)));
|
||||
BigDecimal annualWeight = huAnnualAmount.multiply(BigDecimal.valueOf(containerCalculation.getHu().getWeight(WeightUnit.KG)));
|
||||
|
||||
|
|
@ -174,7 +174,7 @@ public class RouteSectionCostCalculationService {
|
|||
result.setWeightPrice(prices.weightPrice);
|
||||
result.setUtilization(!containerCalculation.isWeightExceeded() || !premise.getHuMixable() ? prices.utilization : BigDecimal.valueOf(1.0));
|
||||
|
||||
var chanceRiskFactors = changeRiskFactorCalculationService.getChanceRiskFactors();
|
||||
var chanceRiskFactors = changeRiskFactorCalculationService.getChanceRiskFactors(setId, periodId);
|
||||
|
||||
BigDecimal annualCost = (containerCalculation.isWeightExceeded() ? prices.weightPrice.multiply(annualWeight) : prices.volumePrice.multiply(annualVolume));
|
||||
BigDecimal annualRiskCost = annualCost.multiply(chanceRiskFactors.getRiskFactor());
|
||||
|
|
@ -220,31 +220,32 @@ public class RouteSectionCostCalculationService {
|
|||
return new PriceCalculationResult(volumePrice, weightPrice, utilization);
|
||||
}
|
||||
|
||||
private ContainerRate findContainerRate(RouteSection section, RouteNode fromNode, RouteNode toNode) {
|
||||
private ContainerRate findContainerRate(RouteSection section, RouteNode fromNode, RouteNode toNode, Integer periodId) {
|
||||
return containerRateRepository.findRoute(
|
||||
fromNode.getNodeId(),
|
||||
toNode.getNodeId(),
|
||||
periodId,
|
||||
TransportType.valueOf(section.getTransportType().name()))
|
||||
.orElseThrow(() -> new NoSuchElementException(
|
||||
"ContainerRate not found for route: " + fromNode.getName() + "(" + fromNode.getNodeId() + ")" +
|
||||
" to " + toNode.getName() + "(" + toNode.getNodeId() + ")"));
|
||||
}
|
||||
|
||||
private MatrixRate findMatrixRate(RouteNode fromNode, RouteNode toNode) {
|
||||
return matrixRateRepository.getByCountryIds(fromNode.getCountryId(), toNode.getCountryId())
|
||||
private MatrixRate findMatrixRate(RouteNode fromNode, RouteNode toNode, Integer periodId) {
|
||||
return matrixRateRepository.getByCountryIds(fromNode.getCountryId(), toNode.getCountryId(), periodId)
|
||||
.orElseThrow(() -> new NoSuchElementException(
|
||||
"MatrixRate not found for countries: " + fromNode.getCountryId() +
|
||||
" to " + toNode.getCountryId()));
|
||||
}
|
||||
|
||||
private BigDecimal getUtilization(RateType rateType) {
|
||||
private BigDecimal getUtilization(Integer setId, RateType rateType) {
|
||||
BigDecimal utilization;
|
||||
if (rateType == RateType.NEAR_BY) {
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CONTAINER_UTIL).orElseThrow().getCurrentValue()));
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CONTAINER_UTIL, setId).orElseThrow().getCurrentValue()));
|
||||
} else if (rateType == RateType.CONTAINER) {
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CONTAINER_UTIL).orElseThrow().getCurrentValue()));
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CONTAINER_UTIL, setId).orElseThrow().getCurrentValue()));
|
||||
} else if (rateType == RateType.MATRIX) {
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.TRUCK_UTIL).orElseThrow().getCurrentValue()));
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.TRUCK_UTIL, setId).orElseThrow().getCurrentValue()));
|
||||
} else
|
||||
throw new IllegalArgumentException("Unknown rate type");
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ public class ShippingFrequencyCalculationService {
|
|||
this.propertyRepository = propertyRepository;
|
||||
}
|
||||
|
||||
public int doCalculation(int huAnnualAmount) {
|
||||
var minAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MIN).orElseThrow().getCurrentValue());
|
||||
var maxAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MAX).orElseThrow().getCurrentValue());
|
||||
public int doCalculation(Integer setId, int huAnnualAmount) {
|
||||
var minAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MIN, setId).orElseThrow().getCurrentValue());
|
||||
var maxAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MAX, setId).orElseThrow().getCurrentValue());
|
||||
|
||||
if (huAnnualAmount > maxAnnualFrequency)
|
||||
return maxAnnualFrequency;
|
||||
|
|
@ -24,9 +24,9 @@ public class ShippingFrequencyCalculationService {
|
|||
|
||||
}
|
||||
|
||||
public double doCalculation(double huAnnualAmount) {
|
||||
Integer minAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MIN).orElseThrow().getCurrentValue());
|
||||
Integer maxAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MAX).orElseThrow().getCurrentValue());
|
||||
public double doCalculation(Integer setId, double huAnnualAmount) {
|
||||
Integer minAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MIN, setId).orElseThrow().getCurrentValue());
|
||||
Integer maxAnnualFrequency = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FREQ_MAX, setId).orElseThrow().getCurrentValue());
|
||||
|
||||
if (huAnnualAmount > maxAnnualFrequency.doubleValue())
|
||||
return maxAnnualFrequency;
|
||||
|
|
|
|||
|
|
@ -1,24 +1,32 @@
|
|||
package de.avatic.lcc.service.precalculation;
|
||||
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
import de.avatic.lcc.dto.generic.RateType;
|
||||
import de.avatic.lcc.model.nodes.Node;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.premises.route.Route;
|
||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||
import de.avatic.lcc.model.properties.PropertySet;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.rates.ValidityPeriod;
|
||||
import de.avatic.lcc.model.rates.ValidityPeriodState;
|
||||
import de.avatic.lcc.model.utils.WeightUnit;
|
||||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.repositories.premise.DestinationRepository;
|
||||
import de.avatic.lcc.repositories.premise.PremiseRepository;
|
||||
import de.avatic.lcc.repositories.premise.RouteRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.service.api.CustomApiService;
|
||||
import de.avatic.lcc.repositories.premise.*;
|
||||
import de.avatic.lcc.repositories.properties.PropertySetRepository;
|
||||
import de.avatic.lcc.repositories.rates.ContainerRateRepository;
|
||||
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
||||
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
|
||||
import de.avatic.lcc.service.access.PropertyService;
|
||||
import de.avatic.lcc.service.api.CustomApiService;
|
||||
import de.avatic.lcc.service.transformer.generic.DimensionTransformer;
|
||||
import de.avatic.lcc.util.exception.internalerror.PremiseValidationError;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
|
|
@ -32,28 +40,39 @@ public class PreCalculationCheckService {
|
|||
private final RouteRepository routeRepository;
|
||||
private final NodeRepository nodeRepository;
|
||||
private final DimensionTransformer dimensionTransformer;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final PropertyService propertyService;
|
||||
|
||||
public PreCalculationCheckService(PremiseRepository premiseRepository, CustomApiService customApiService, DestinationRepository destinationRepository, RouteRepository routeRepository, NodeRepository nodeRepository, DimensionTransformer dimensionTransformer, PropertyRepository propertyRepository, PropertyService propertyService) {
|
||||
private final PropertyService propertyService;
|
||||
private final RouteSectionRepository routeSectionRepository;
|
||||
private final RouteNodeRepository routeNodeRepository;
|
||||
private final MatrixRateRepository matrixRateRepository;
|
||||
private final ContainerRateRepository containerRateRepository;
|
||||
private final ValidityPeriodRepository validityPeriodRepository;
|
||||
private final PropertySetRepository propertySetRepository;
|
||||
|
||||
public PreCalculationCheckService(PremiseRepository premiseRepository, CustomApiService customApiService, DestinationRepository destinationRepository, RouteRepository routeRepository, NodeRepository nodeRepository, DimensionTransformer dimensionTransformer, PropertyService propertyService, RouteSectionRepository routeSectionRepository, RouteNodeRepository routeNodeRepository, MatrixRateRepository matrixRateRepository, ContainerRateRepository containerRateRepository, ValidityPeriodRepository validityPeriodRepository, PropertySetRepository propertySetRepository) {
|
||||
this.premiseRepository = premiseRepository;
|
||||
this.customApiService = customApiService;
|
||||
this.destinationRepository = destinationRepository;
|
||||
this.routeRepository = routeRepository;
|
||||
this.nodeRepository = nodeRepository;
|
||||
this.dimensionTransformer = dimensionTransformer;
|
||||
this.propertyRepository = propertyRepository;
|
||||
|
||||
this.propertyService = propertyService;
|
||||
this.routeSectionRepository = routeSectionRepository;
|
||||
this.routeNodeRepository = routeNodeRepository;
|
||||
this.matrixRateRepository = matrixRateRepository;
|
||||
this.containerRateRepository = containerRateRepository;
|
||||
this.validityPeriodRepository = validityPeriodRepository;
|
||||
this.propertySetRepository = propertySetRepository;
|
||||
}
|
||||
|
||||
public void doPrecheck(Integer premiseId) {
|
||||
public void doPrecheck(Integer premiseId, Integer setId, Integer periodId) {
|
||||
var premise = premiseRepository.getPremiseById(premiseId).orElseThrow();
|
||||
|
||||
supplierCheck(premise);
|
||||
|
||||
materialCheck(premise);
|
||||
|
||||
|
||||
packagingCheck(premise);
|
||||
|
||||
priceCheck(premise);
|
||||
|
|
@ -88,10 +107,68 @@ 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);
|
||||
|
||||
routes.stream().filter(Route::getSelected).findAny().ifPresent(r -> {
|
||||
var sections = routeSectionRepository.getByRouteId(r.getId());
|
||||
routeCheck(sections, period);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void periodCheck(ValidityPeriod period, PropertySet set) {
|
||||
|
||||
|
||||
if(set == null)
|
||||
throw new PremiseValidationError("There are no system properties for the given date.");
|
||||
|
||||
if(period == null)
|
||||
throw new PremiseValidationError("There are no rates for the given date.");
|
||||
|
||||
if(ValidityPeriodState.VALID != period.getState() && ValidityPeriodState.EXPIRED != period.getState())
|
||||
throw new PremiseValidationError("There are no valid rates for the given date.");
|
||||
|
||||
if(ValidityPeriodState.VALID != set.getState() && ValidityPeriodState.EXPIRED != period.getState())
|
||||
throw new PremiseValidationError("There are no valid system properties for the given date.");
|
||||
|
||||
}
|
||||
|
||||
private void routeCheck(List<RouteSection> sections, ValidityPeriod period) {
|
||||
|
||||
sections.forEach(section -> {
|
||||
var fromRouteNode = routeNodeRepository.getFromNodeBySectionId(section.getId());
|
||||
var toRouteNode = routeNodeRepository.getToNodeBySectionId(section.getId());
|
||||
|
||||
if (fromRouteNode.isEmpty() || toRouteNode.isEmpty())
|
||||
throw new PremiseValidationError("Error in route. Please contact your administrator.");
|
||||
|
||||
if (RateType.MATRIX == section.getRateType()) {
|
||||
var rate = matrixRateRepository.getByCountryIds(fromRouteNode.get().getCountryId(), toRouteNode.get().getCountryId(), period.getId());
|
||||
|
||||
|
||||
if (rate.isEmpty())
|
||||
throw new PremiseValidationError("The transport rates for the period " + period.getStartDate().format(DateTimeFormatter.ISO_DATE) + " to " + period.getEndDate().format(DateTimeFormatter.ISO_DATE) + " are insufficient to perform the calculation for route segment" + fromRouteNode.get().getExternalMappingId() + " to " + toRouteNode.get().getExternalMappingId());
|
||||
|
||||
}
|
||||
|
||||
if (RateType.CONTAINER == section.getRateType()) {
|
||||
var rate = containerRateRepository.findRoute(fromRouteNode.get().getNodeId(), toRouteNode.get().getNodeId(), period.getId(), section.getTransportType());
|
||||
|
||||
if (rate.isEmpty())
|
||||
throw new PremiseValidationError("The transport rates for the period " + period.getStartDate().format(DateTimeFormatter.ISO_DATE) + " to " + period.getEndDate().format(DateTimeFormatter.ISO_DATE) + " are insufficient to perform the calculation for route segment" + fromRouteNode.get().getExternalMappingId() + " to " + toRouteNode.get().getExternalMappingId());
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void destinationCheck(Destination destination, Node node) {
|
||||
|
||||
if (destination.getAnnualAmount() == null || destination.getAnnualAmount() == 0)
|
||||
|
|
@ -216,7 +293,7 @@ public class PreCalculationCheckService {
|
|||
}
|
||||
|
||||
|
||||
if((hu.getLength() * hu.getWidth()) < 20000) {
|
||||
if ((hu.getLength() * hu.getWidth()) < 20000) {
|
||||
throw new PremiseValidationError("HU dimensions too small. Review entered length, width, height and selected dimension unit [mm, cm, m].");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue