Refactor calculation services and add SQL node data
This commit restructures various calculation services, consolidating and relocating them to improve modularity and clarity. Additionally, it introduces initial SQL insert statements for 'node' entities, laying the groundwork for data mapping and geography-based functionalities.
This commit is contained in:
parent
9bbc648757
commit
270914b7cd
52 changed files with 1246945 additions and 524 deletions
|
|
@ -0,0 +1,54 @@
|
|||
package de.avatic.lcc.calculationmodel;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class AirfreightResult {
|
||||
|
||||
private BigDecimal maxAirfreightShare;
|
||||
private BigDecimal airFreightShare;
|
||||
|
||||
private BigDecimal weight;
|
||||
private BigDecimal volumetricWeight;
|
||||
|
||||
private BigDecimal annualCost;
|
||||
|
||||
public BigDecimal getMaxAirfreightShare() {
|
||||
return maxAirfreightShare;
|
||||
}
|
||||
|
||||
public void setMaxAirfreightShare(BigDecimal maxAirfreightShare) {
|
||||
this.maxAirfreightShare = maxAirfreightShare;
|
||||
}
|
||||
|
||||
public BigDecimal getAirFreightShare() {
|
||||
return airFreightShare;
|
||||
}
|
||||
|
||||
public void setAirFreightShare(BigDecimal airFreightShare) {
|
||||
this.airFreightShare = airFreightShare;
|
||||
}
|
||||
|
||||
public BigDecimal getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(BigDecimal weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public BigDecimal getVolumetricWeight() {
|
||||
return volumetricWeight;
|
||||
}
|
||||
|
||||
public void setVolumetricWeight(BigDecimal volumetricWeight) {
|
||||
this.volumetricWeight = volumetricWeight;
|
||||
}
|
||||
|
||||
public BigDecimal getAnnualCost() {
|
||||
return annualCost;
|
||||
}
|
||||
|
||||
public void setAnnualCost(BigDecimal annualCost) {
|
||||
this.annualCost = annualCost;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package de.avatic.lcc.calculationmodel;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Represents the result of a chance and risk factor calculation.
|
||||
* This class holds the calculated chance and risk factors used in custom calculations.
|
||||
*/
|
||||
public class ChangeRiskFactorCalculationResult {
|
||||
|
||||
/**
|
||||
* The calculated chance factor value
|
||||
*/
|
||||
private BigDecimal chanceFactor;
|
||||
|
||||
/**
|
||||
* The calculated risk factor value
|
||||
*/
|
||||
private BigDecimal riskFactor;
|
||||
|
||||
|
||||
/**
|
||||
* @return the chance factor value
|
||||
*/
|
||||
public BigDecimal getChanceFactor() {
|
||||
return chanceFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param chanceFactor the chance factor value to set
|
||||
*/
|
||||
public void setChanceFactor(BigDecimal chanceFactor) {
|
||||
this.chanceFactor = chanceFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the risk factor value
|
||||
*/
|
||||
public BigDecimal getRiskFactor() {
|
||||
return riskFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param riskFactor the risk factor value to set
|
||||
*/
|
||||
public void setRiskFactor(BigDecimal riskFactor) {
|
||||
this.riskFactor = riskFactor;
|
||||
}
|
||||
}
|
||||
189
src/main/java/de/avatic/lcc/calculationmodel/CustomResult.java
Normal file
189
src/main/java/de/avatic/lcc/calculationmodel/CustomResult.java
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
package de.avatic.lcc.calculationmodel;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
/**
|
||||
* Represents the result of a custom calculation containing values related to customs duties and costs.
|
||||
* This class holds information about custom value, duties, rates and annual costs.
|
||||
*/
|
||||
public class CustomResult {
|
||||
|
||||
/**
|
||||
* Represents an empty calculation result with all values set to zero
|
||||
*/
|
||||
public static final CustomResult EMPTY = new CustomResult(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
|
||||
|
||||
/**
|
||||
* The custom value used in calculation
|
||||
*/
|
||||
BigDecimal customValue;
|
||||
|
||||
/**
|
||||
* The custom risk value used in calculation
|
||||
*/
|
||||
BigDecimal customRiskValue;
|
||||
|
||||
/**
|
||||
* The custom chance value used in calculation
|
||||
*/
|
||||
BigDecimal customChanceValue;
|
||||
|
||||
/**
|
||||
* The calculated custom duties
|
||||
*/
|
||||
BigDecimal customDuties;
|
||||
/**
|
||||
* The custom rate applied in calculation
|
||||
*/
|
||||
BigDecimal tariffRate;
|
||||
/**
|
||||
* The calculated annual cost
|
||||
*/
|
||||
BigDecimal annualCost;
|
||||
|
||||
/**
|
||||
* The calculated annual risk cost
|
||||
*/
|
||||
BigDecimal annualRiskCost;
|
||||
|
||||
/**
|
||||
* The calculated annual chance cost
|
||||
*/
|
||||
BigDecimal annualChanceCost;
|
||||
|
||||
/**
|
||||
* Constructs a CustomCalculationResult with the provided values for custom calculations.
|
||||
*
|
||||
* @param customValue the custom value used in the calculation
|
||||
* @param customRiskValue the calculated custom risk value
|
||||
* @param customChanceValue the calculated custom chance value
|
||||
* @param customDuties the custom duties amount
|
||||
* @param tariffRate the applicable tariff rate
|
||||
* @param annualCost the total annual cost
|
||||
* @param annualRiskCost the annual risk-related cost
|
||||
* @param annualChanceCost the annual chance-related cost
|
||||
*/
|
||||
public CustomResult(BigDecimal customValue, BigDecimal customRiskValue, BigDecimal customChanceValue, BigDecimal customDuties, BigDecimal tariffRate, BigDecimal annualCost, BigDecimal annualRiskCost, BigDecimal annualChanceCost) {
|
||||
this.customValue = customValue;
|
||||
this.customDuties = customDuties;
|
||||
this.tariffRate = tariffRate;
|
||||
this.annualCost = annualCost;
|
||||
this.annualRiskCost = annualRiskCost;
|
||||
this.annualChanceCost = annualChanceCost;
|
||||
this.customRiskValue = customRiskValue;
|
||||
this.customChanceValue = customChanceValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the custom risk value
|
||||
*/
|
||||
public BigDecimal getCustomRiskValue() {
|
||||
return customRiskValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param customRiskValue the custom risk value to set
|
||||
*/
|
||||
public void setCustomRiskValue(BigDecimal customRiskValue) {
|
||||
this.customRiskValue = customRiskValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the custom chance value
|
||||
*/
|
||||
public BigDecimal getCustomChanceValue() {
|
||||
return customChanceValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param customChanceValue the custom chance value to set
|
||||
*/
|
||||
public void setCustomChanceValue(BigDecimal customChanceValue) {
|
||||
this.customChanceValue = customChanceValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the annual risk cost
|
||||
*/
|
||||
public BigDecimal getAnnualRiskCost() {
|
||||
return annualRiskCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param annualRiskCost the annual risk cost to set
|
||||
*/
|
||||
public void setAnnualRiskCost(BigDecimal annualRiskCost) {
|
||||
this.annualRiskCost = annualRiskCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the annual chance cost
|
||||
*/
|
||||
public BigDecimal getAnnualChanceCost() {
|
||||
return annualChanceCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param annualChanceCost the annual chance cost to set
|
||||
*/
|
||||
public void setAnnualChanceCost(BigDecimal annualChanceCost) {
|
||||
this.annualChanceCost = annualChanceCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the custom value
|
||||
*/
|
||||
public BigDecimal getCustomValue() {
|
||||
return customValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param customValue the custom value to set
|
||||
*/
|
||||
public void setCustomValue(BigDecimal customValue) {
|
||||
this.customValue = customValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the custom duties
|
||||
*/
|
||||
public BigDecimal getCustomDuties() {
|
||||
return customDuties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param customDuties the custom duties to set
|
||||
*/
|
||||
public void setCustomDuties(BigDecimal customDuties) {
|
||||
this.customDuties = customDuties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the custom rate
|
||||
*/
|
||||
public BigDecimal getTariffRate() {
|
||||
return tariffRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tariffRate the custom rate to set
|
||||
*/
|
||||
public void setTariffRate(BigDecimal tariffRate) {
|
||||
this.tariffRate = tariffRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the annual cost
|
||||
*/
|
||||
public BigDecimal getAnnualCost() {
|
||||
return annualCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param annualCost the annual cost to set
|
||||
*/
|
||||
public void setAnnualCost(BigDecimal annualCost) {
|
||||
this.annualCost = annualCost;
|
||||
}
|
||||
}
|
||||
131
src/main/java/de/avatic/lcc/calculationmodel/HandlingResult.java
Normal file
131
src/main/java/de/avatic/lcc/calculationmodel/HandlingResult.java
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
package de.avatic.lcc.calculationmodel;
|
||||
|
||||
import de.avatic.lcc.model.packaging.LoadCarrierType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Represents the results of handling cost calculations for packaging units.
|
||||
* This class contains annual costs related to handling, repacking, and disposal operations.
|
||||
*/
|
||||
public class HandlingResult {
|
||||
|
||||
/**
|
||||
* Indicates whether the handling unit is classified as a small unit
|
||||
*/
|
||||
private LoadCarrierType loadCarrierType;
|
||||
/**
|
||||
* Annual costs associated with repacking operations
|
||||
*/
|
||||
private BigDecimal annualRepackingCost;
|
||||
/**
|
||||
* Annual costs associated with handling operations
|
||||
*/
|
||||
private BigDecimal annualHandlingCost;
|
||||
/**
|
||||
* Annual costs associated with disposal operations
|
||||
*/
|
||||
private BigDecimal annualDisposalCost;
|
||||
/**
|
||||
* Total annual costs combining all handling-related expenses
|
||||
*/
|
||||
private BigDecimal annualCost;
|
||||
|
||||
public HandlingResult(LoadCarrierType loadCarrierType, BigDecimal annualRepackingCost, BigDecimal annualHandlingCost, BigDecimal annualDisposalCost, BigDecimal annualCost) {
|
||||
this.loadCarrierType = loadCarrierType;
|
||||
this.annualRepackingCost = annualRepackingCost;
|
||||
this.annualHandlingCost = annualHandlingCost;
|
||||
this.annualDisposalCost = annualDisposalCost;
|
||||
this.annualCost = annualCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the indicator whether the unit is classified as small
|
||||
*
|
||||
* @return true if the unit is small, false otherwise
|
||||
*/
|
||||
public LoadCarrierType getLoadCarrierType() {
|
||||
return loadCarrierType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the small unit indicator
|
||||
*
|
||||
* @param loadCarrierType the small unit indicator to set
|
||||
*/
|
||||
public void setLoadCarrierType(LoadCarrierType loadCarrierType) {
|
||||
this.loadCarrierType = loadCarrierType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annual repacking cost
|
||||
*
|
||||
* @return the annual repacking cost
|
||||
*/
|
||||
public BigDecimal getAnnualRepackingCost() {
|
||||
return annualRepackingCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the annual repacking cost
|
||||
*
|
||||
* @param annualRepackingCost the annual repacking cost to set
|
||||
*/
|
||||
public void setAnnualRepackingCost(BigDecimal annualRepackingCost) {
|
||||
this.annualRepackingCost = annualRepackingCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annual handling cost
|
||||
*
|
||||
* @return the annual handling cost
|
||||
*/
|
||||
public BigDecimal getAnnualHandlingCost() {
|
||||
return annualHandlingCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the annual handling cost
|
||||
*
|
||||
* @param annualHandlingCost the annual handling cost to set
|
||||
*/
|
||||
public void setAnnualHandlingCost(BigDecimal annualHandlingCost) {
|
||||
this.annualHandlingCost = annualHandlingCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annual disposal cost
|
||||
*
|
||||
* @return the annual disposal cost
|
||||
*/
|
||||
public BigDecimal getAnnualDisposalCost() {
|
||||
return annualDisposalCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the annual disposal cost
|
||||
*
|
||||
* @param annualDisposalCost the annual disposal cost to set
|
||||
*/
|
||||
public void setAnnualDisposalCost(BigDecimal annualDisposalCost) {
|
||||
this.annualDisposalCost = annualDisposalCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total annual cost
|
||||
*
|
||||
* @return the total annual cost
|
||||
*/
|
||||
public BigDecimal getAnnualCost() {
|
||||
return annualCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total annual cost
|
||||
*
|
||||
* @param annualCost the total annual cost to set
|
||||
*/
|
||||
public void setAnnualCost(BigDecimal annualCost) {
|
||||
this.annualCost = annualCost;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
package de.avatic.lcc.calculationmodel;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Represents the results of inventory cost calculations.
|
||||
* This class contains various inventory-related metrics and associated costs
|
||||
* including safety stock levels, inventory in different states, and annual costs.
|
||||
*/
|
||||
public class InventoryCostResult {
|
||||
|
||||
private BigDecimal safetyStockInDays;
|
||||
/**
|
||||
* The operational stock level maintained for regular operations
|
||||
*/
|
||||
private BigDecimal operationalStock;
|
||||
/**
|
||||
* The safety stock level maintained as buffer against uncertainties
|
||||
*/
|
||||
private BigDecimal safetyStock;
|
||||
/**
|
||||
* The amount of inventory physically stored in warehouses
|
||||
*/
|
||||
private BigDecimal stockedInventory;
|
||||
/**
|
||||
* The amount of inventory currently in transit
|
||||
*/
|
||||
private BigDecimal inTransportStock;
|
||||
/**
|
||||
* The amount of stock before payment is due
|
||||
*/
|
||||
private BigDecimal stockBeforePayment;
|
||||
/**
|
||||
* Annual costs related to capital investment in inventory
|
||||
*/
|
||||
private BigDecimal annualCapitalCost;
|
||||
/**
|
||||
* Annual costs associated with storing inventory
|
||||
*/
|
||||
private BigDecimal annualStorageCost;
|
||||
|
||||
|
||||
public InventoryCostResult(BigDecimal operationalStock, BigDecimal safetyStock, BigDecimal stockedInventory, BigDecimal inTransportStock, BigDecimal stockBeforePayment, BigDecimal annualCapitalCost, BigDecimal annualStorageCost, BigDecimal safetyStockInDays) {
|
||||
this.operationalStock = operationalStock;
|
||||
this.safetyStock = safetyStock;
|
||||
this.stockedInventory = stockedInventory;
|
||||
this.inTransportStock = inTransportStock;
|
||||
this.stockBeforePayment = stockBeforePayment;
|
||||
this.annualCapitalCost = annualCapitalCost;
|
||||
this.annualStorageCost = annualStorageCost;
|
||||
this.safetyStockInDays = safetyStockInDays;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the operational stock level
|
||||
*
|
||||
* @return the operational stock level
|
||||
*/
|
||||
public BigDecimal getOperationalStock() {
|
||||
return operationalStock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operational stock level
|
||||
*
|
||||
* @param operationalStock the operational stock level to set
|
||||
*/
|
||||
public void setOperationalStock(BigDecimal operationalStock) {
|
||||
this.operationalStock = operationalStock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the safety stock level
|
||||
*
|
||||
* @return the safety stock level
|
||||
*/
|
||||
public BigDecimal getSafetyStock() {
|
||||
return safetyStock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the safety stock level
|
||||
*
|
||||
* @param safetyStock the safety stock level to set
|
||||
*/
|
||||
public void setSafetyStock(BigDecimal safetyStock) {
|
||||
this.safetyStock = safetyStock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stocked inventory amount
|
||||
*
|
||||
* @return the stocked inventory amount
|
||||
*/
|
||||
public BigDecimal getStockedInventory() {
|
||||
return stockedInventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stocked inventory amount
|
||||
*
|
||||
* @param stockedInventory the stocked inventory amount to set
|
||||
*/
|
||||
public void setStockedInventory(BigDecimal stockedInventory) {
|
||||
this.stockedInventory = stockedInventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the in-transport stock amount
|
||||
*
|
||||
* @return the in-transport stock amount
|
||||
*/
|
||||
public BigDecimal getInTransportStock() {
|
||||
return inTransportStock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the in-transport stock amount
|
||||
*
|
||||
* @param inTransportStock the in-transport stock amount to set
|
||||
*/
|
||||
public void setInTransportStock(BigDecimal inTransportStock) {
|
||||
this.inTransportStock = inTransportStock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stock amount before payment
|
||||
*
|
||||
* @return the stock amount before payment
|
||||
*/
|
||||
public BigDecimal getStockBeforePayment() {
|
||||
return stockBeforePayment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stock amount before payment
|
||||
*
|
||||
* @param stockBeforePayment the stock amount before payment to set
|
||||
*/
|
||||
public void setStockBeforePayment(BigDecimal stockBeforePayment) {
|
||||
this.stockBeforePayment = stockBeforePayment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annual capital cost
|
||||
*
|
||||
* @return the annual capital cost
|
||||
*/
|
||||
public BigDecimal getAnnualCapitalCost() {
|
||||
return annualCapitalCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the annual capital cost
|
||||
*
|
||||
* @param annualCapitalCost the annual capital cost to set
|
||||
*/
|
||||
public void setAnnualCapitalCost(BigDecimal annualCapitalCost) {
|
||||
this.annualCapitalCost = annualCapitalCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the annual storage cost
|
||||
*
|
||||
* @return the annual storage cost
|
||||
*/
|
||||
public BigDecimal getAnnualStorageCost() {
|
||||
return annualStorageCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the annual storage cost
|
||||
*
|
||||
* @param annualStorageCost the annual storage cost to set
|
||||
*/
|
||||
public void setAnnualStorageCost(BigDecimal annualStorageCost) {
|
||||
this.annualStorageCost = annualStorageCost;
|
||||
}
|
||||
|
||||
public BigDecimal getSafetyStockInDays() {
|
||||
return safetyStockInDays;
|
||||
}
|
||||
|
||||
public void setSafetyStockInDays(BigDecimal safetyStockInDays) {
|
||||
this.safetyStockInDays = safetyStockInDays;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package de.avatic.lcc.calculationmodel;
|
||||
|
||||
import de.avatic.lcc.model.calculations.CalculationJobRouteSection;
|
||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||
|
||||
public record SectionInfo(RouteSection section, CalculationJobRouteSection result, ContainerCalculationResult containerResult) {
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package de.avatic.lcc.controller.calculation;
|
||||
|
||||
|
||||
import de.avatic.lcc.dto.bulk.BulkStatus;
|
||||
import de.avatic.lcc.dto.calculation.edit.SetDataDTO;
|
||||
import de.avatic.lcc.dto.calculation.create.PremiseSearchResultDTO;
|
||||
import de.avatic.lcc.dto.calculation.edit.*;
|
||||
|
|
@ -68,12 +69,23 @@ public class PremiseController {
|
|||
return ResponseEntity.ok(premisesServices.getPremises(premissIds));
|
||||
}
|
||||
|
||||
// triggers a calculation
|
||||
@PutMapping("/done")
|
||||
public ResponseEntity<Integer> completePremises(@RequestBody List<Integer> premiseIds) {
|
||||
@PutMapping("/start")
|
||||
public ResponseEntity<Integer> startCalculation(@RequestBody List<Integer> premiseIds) {
|
||||
return ResponseEntity.ok(premisesServices.startCalculation(premiseIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current status of a specific calculation processing operation.
|
||||
*
|
||||
* @param id The unique identifier of the operation (processing_id) to check its status.
|
||||
* @return A ResponseEntity with the bulk processing status payload.
|
||||
*/
|
||||
@GetMapping("/status/{processing_id}")
|
||||
public ResponseEntity<BulkStatus> getUploadStatus(@PathVariable("processing_id") Integer id) {
|
||||
return ResponseEntity.ok(premisesServices.getCalculationStatus(id));
|
||||
}
|
||||
|
||||
|
||||
@PutMapping("/packaging")
|
||||
public ResponseEntity<HashMap<String, String>> updatePackaging(@RequestBody PackagingUpdateDTO packagingDTO) {
|
||||
return ResponseEntity.ok(premisesServices.updatePackaging(packagingDTO));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package de.avatic.lcc.dto.calculation;
|
||||
|
||||
import de.avatic.lcc.model.calculations.CalculationJobState;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CalculationStatus {
|
||||
|
||||
private Integer processId;
|
||||
|
||||
private Map<Integer, CalculationJobState> jobStates;
|
||||
private Map<Integer, String> exceptionMessages;
|
||||
|
||||
}
|
||||
|
|
@ -22,7 +22,6 @@ public class CalculationJob {
|
|||
|
||||
private Integer userId;
|
||||
|
||||
private BigDecimal weightedTotalCosts;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
|
|
@ -80,11 +79,4 @@ public class CalculationJob {
|
|||
this.userId = userId;
|
||||
}
|
||||
|
||||
public BigDecimal getWeightedTotalCosts() {
|
||||
return weightedTotalCosts;
|
||||
}
|
||||
|
||||
public void setWeightedTotalCosts(BigDecimal weightedTotalCosts) {
|
||||
this.weightedTotalCosts = weightedTotalCosts;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package de.avatic.lcc.model.calculations;
|
||||
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public class CalculationJobDestination {
|
||||
private Integer id;
|
||||
|
|
@ -12,8 +13,8 @@ public class CalculationJobDestination {
|
|||
private BigDecimal annualAmount;
|
||||
|
||||
// Risk
|
||||
private BigDecimal annualRiskCost;
|
||||
private BigDecimal annualChanceCost;
|
||||
private BigDecimal totalRiskCost;
|
||||
private BigDecimal totalChanceCost;
|
||||
|
||||
// Handling
|
||||
private Boolean isSmallUnit;
|
||||
|
|
@ -24,6 +25,7 @@ public class CalculationJobDestination {
|
|||
// Inventory
|
||||
private BigDecimal operationalStock;
|
||||
private BigDecimal safetyStock;
|
||||
private BigDecimal safetyStockInDays;
|
||||
private BigDecimal stockedInventory;
|
||||
private BigDecimal inTransportStock;
|
||||
private BigDecimal stockBeforePayment;
|
||||
|
|
@ -44,8 +46,8 @@ public class CalculationJobDestination {
|
|||
private BigDecimal annualAirFreightCost;
|
||||
|
||||
// Transportation
|
||||
private String transportationType;
|
||||
private Integer huPerLayer;
|
||||
private ContainerType containerType;
|
||||
private Integer huCount;
|
||||
private String layerStructure; // JSON as String
|
||||
private Integer layerCount;
|
||||
private Boolean transportWeightExceeded;
|
||||
|
|
@ -125,20 +127,20 @@ public class CalculationJobDestination {
|
|||
this.totalCost = totalCost;
|
||||
}
|
||||
|
||||
public BigDecimal getAnnualRiskCost() {
|
||||
return annualRiskCost;
|
||||
public BigDecimal getTotalRiskCost() {
|
||||
return totalRiskCost;
|
||||
}
|
||||
|
||||
public void setAnnualRiskCost(BigDecimal annualRiskCost) {
|
||||
this.annualRiskCost = annualRiskCost;
|
||||
public void setTotalRiskCost(BigDecimal totalRiskCost) {
|
||||
this.totalRiskCost = totalRiskCost;
|
||||
}
|
||||
|
||||
public BigDecimal getAnnualChanceCost() {
|
||||
return annualChanceCost;
|
||||
public BigDecimal getTotalChanceCost() {
|
||||
return totalChanceCost;
|
||||
}
|
||||
|
||||
public void setAnnualChanceCost(BigDecimal annualChanceCost) {
|
||||
this.annualChanceCost = annualChanceCost;
|
||||
public void setTotalChanceCost(BigDecimal totalChanceCost) {
|
||||
this.totalChanceCost = totalChanceCost;
|
||||
}
|
||||
|
||||
public Boolean getSmallUnit() {
|
||||
|
|
@ -301,20 +303,20 @@ public class CalculationJobDestination {
|
|||
this.annualAirFreightCost = annualAirFreightCost;
|
||||
}
|
||||
|
||||
public String getTransportationType() {
|
||||
return transportationType;
|
||||
public ContainerType getContainerType() {
|
||||
return containerType;
|
||||
}
|
||||
|
||||
public void setTransportationType(String transportationType) {
|
||||
this.transportationType = transportationType;
|
||||
public void setContainerType(ContainerType containerType) {
|
||||
this.containerType = containerType;
|
||||
}
|
||||
|
||||
public Integer getHuPerLayer() {
|
||||
return huPerLayer;
|
||||
public Integer getHuCount() {
|
||||
return huCount;
|
||||
}
|
||||
|
||||
public void setHuPerLayer(Integer huPerLayer) {
|
||||
this.huPerLayer = huPerLayer;
|
||||
public void setHuCount(Integer huCount) {
|
||||
this.huCount = huCount;
|
||||
}
|
||||
|
||||
public String getLayerStructure() {
|
||||
|
|
@ -373,4 +375,11 @@ public class CalculationJobDestination {
|
|||
this.fcaCost = fcaCost;
|
||||
}
|
||||
|
||||
public void setSafetyStockInDays(BigDecimal safetyStockInDays) {
|
||||
this.safetyStockInDays = safetyStockInDays;
|
||||
}
|
||||
|
||||
public BigDecimal getSafetyStockInDays() {
|
||||
return safetyStockInDays;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,29 @@
|
|||
private BigDecimal distance;
|
||||
private BigDecimal cbmPrice;
|
||||
private BigDecimal weightPrice;
|
||||
|
||||
private BigDecimal annualRiskCost;
|
||||
private BigDecimal annualChanceCost;
|
||||
private BigDecimal annualCost;
|
||||
private Integer transitTime;
|
||||
|
||||
|
||||
public BigDecimal getAnnualRiskCost() {
|
||||
return annualRiskCost;
|
||||
}
|
||||
|
||||
public void setAnnualRiskCost(BigDecimal annualRiskCost) {
|
||||
this.annualRiskCost = annualRiskCost;
|
||||
}
|
||||
|
||||
public BigDecimal getAnnualChanceCost() {
|
||||
return annualChanceCost;
|
||||
}
|
||||
|
||||
public void setAnnualChanceCost(BigDecimal annualChanceCost) {
|
||||
this.annualChanceCost = annualChanceCost;
|
||||
}
|
||||
|
||||
public RateType getRateType() {
|
||||
return rateType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package de.avatic.lcc.model.packaging;
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration representing different types of load carriers used in logistics.
|
||||
* These are standardized containers used for transporting goods.
|
||||
*/
|
||||
public enum LoadCarrierType {
|
||||
/**
|
||||
* Small Load Carrier (SLC) - A smaller standardized container used for
|
||||
* transporting smaller quantities of goods or materials.
|
||||
*/
|
||||
SLC,
|
||||
|
||||
/**
|
||||
* Large Load Carrier (LLC) - A larger standardized container used for
|
||||
* transporting bigger quantities of goods or materials.
|
||||
*/
|
||||
LLC
|
||||
}
|
||||
|
|
@ -125,10 +125,24 @@ public class PackagingDimension {
|
|||
}
|
||||
|
||||
public double getVolume(DimensionUnit unit) {
|
||||
var lengthInM = unit.convertFromMM(length);
|
||||
var widthInM = unit.convertFromMM(width);
|
||||
var heightInM = unit.convertFromMM(height);
|
||||
var lengthInX = unit.convertFromMM(length);
|
||||
var widthInX = unit.convertFromMM(width);
|
||||
var heightInX = unit.convertFromMM(height);
|
||||
|
||||
return lengthInM.doubleValue() * widthInM.doubleValue() * heightInM.doubleValue();
|
||||
return lengthInX.doubleValue() * widthInX.doubleValue() * heightInX.doubleValue();
|
||||
}
|
||||
|
||||
public LoadCarrierType getLoadCarrierType() {
|
||||
return getVolume(DimensionUnit.MM) > 80000000 ? LoadCarrierType.LLC : LoadCarrierType.SLC;
|
||||
}
|
||||
|
||||
public double getRoundedHeight(DimensionUnit unit) {
|
||||
return Math.ceil(unit.convertFromMM(height).doubleValue());
|
||||
}
|
||||
|
||||
public double getFloorArea(DimensionUnit unit) {
|
||||
var lengthInX = unit.convertFromMM(length);
|
||||
var widthInX = unit.convertFromMM(width);
|
||||
return lengthInX.doubleValue() * widthInX.doubleValue();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ public class Destination {
|
|||
|
||||
private Boolean isD2d;
|
||||
|
||||
private int leadTimeD2d;
|
||||
|
||||
private BigDecimal repackingCost;
|
||||
|
||||
private BigDecimal handlingCost;
|
||||
|
|
@ -29,6 +31,14 @@ public class Destination {
|
|||
|
||||
private Integer countryId;
|
||||
|
||||
public int getLeadTimeD2d() {
|
||||
return leadTimeD2d;
|
||||
}
|
||||
|
||||
public void setLeadTimeD2d(int leadTimeD2d) {
|
||||
this.leadTimeD2d = leadTimeD2d;
|
||||
}
|
||||
|
||||
public Integer getCountryId() {
|
||||
return countryId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package de.avatic.lcc.model.properties;
|
|||
|
||||
public enum SystemPropertyMappingId {
|
||||
|
||||
|
||||
PAYMENT_TERMS("Payment terms [days]", "30"),
|
||||
WORKDAYS("Annual working days", "210"),
|
||||
INTEREST_RATE("Interest rate inventory [%]", "12%"),
|
||||
FCA_FEE("FCA fee [%]", "0,20%"),
|
||||
|
|
@ -9,13 +11,11 @@ public enum SystemPropertyMappingId {
|
|||
CUSTOM_FEE("Customs clearance fee per import & HS code", "35,00 €"),
|
||||
REPORTING("Standard-Report Format", "MEK_B"),
|
||||
|
||||
|
||||
FEU("40'", "Yes"),
|
||||
TEU("20'", "Yes"),
|
||||
FEU_HQ("40'HC", "Yes"),
|
||||
TEU_HQ("20'HC", "No"),
|
||||
|
||||
|
||||
CONTAINER_UTIL("Container utilization in mixed containers [%]", "70%"),
|
||||
TRUCK_UTIL("Truck utilization road transport EMEA [%]", "70%"),
|
||||
VALID_DAYS("Max validity of container freight rates [days]", "60"),
|
||||
|
|
@ -26,7 +26,10 @@ public enum SystemPropertyMappingId {
|
|||
FEU_LOAD("Max load of 40' container [kg]", "21000"),
|
||||
TRUCK_LOAD("Maximum truck load [kg]", "25000"),
|
||||
|
||||
|
||||
START_REF("Reference route segment start node mapping id", "CNXMN"),
|
||||
END_REF("Reference route segment end node mapping id","HAM"),
|
||||
RISK_REF("The historically highest rate for the reference route segment for 40ft containers [EUR]", "1000,00 €"),
|
||||
CHANCE_REF("The historically lowest rate for the reference route segment for 40ft containers [EUR]", "20000,00 €"),
|
||||
|
||||
AIR_PRECARRIAGE("Pre-carriage [EUR/kg]", "0,10"),
|
||||
AIR_HANDLING("Pre-carriage handling [EUR]", "80,00"),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package de.avatic.lcc.repositories.calculation;
|
||||
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobDestination;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
|
@ -40,13 +41,14 @@ public class CalculationJobDestinationRepository {
|
|||
entity.setPremiseDestinationId(rs.getInt("premise_destination_id"));
|
||||
entity.setCalculationJobId(rs.getInt("calculation_job_id"));
|
||||
entity.setSafetyStock(rs.getBigDecimal("safety_stock"));
|
||||
entity.setSafetyStockInDays(rs.getBigDecimal("safety_stock_in_days"));
|
||||
entity.setShippingFrequency(rs.getInt("shipping_frequency"));
|
||||
entity.setTotalCost(rs.getBigDecimal("total_cost"));
|
||||
entity.setTotalCost(rs.getBigDecimal("annual_amount"));
|
||||
entity.setAnnualAmount(rs.getBigDecimal("annual_amount"));
|
||||
|
||||
// Risk fields
|
||||
entity.setAnnualRiskCost(rs.getBigDecimal("annual_risk_cost"));
|
||||
entity.setAnnualChanceCost(rs.getBigDecimal("annual_chance_cost"));
|
||||
entity.setTotalRiskCost(rs.getBigDecimal("annual_risk_cost"));
|
||||
entity.setTotalChanceCost(rs.getBigDecimal("annual_chance_cost"));
|
||||
|
||||
// Handling fields
|
||||
entity.setSmallUnit(rs.getBoolean("is_small_unit"));
|
||||
|
|
@ -77,12 +79,13 @@ public class CalculationJobDestinationRepository {
|
|||
entity.setAnnualAirFreightCost(rs.getBigDecimal("annual_air_freight_cost"));
|
||||
|
||||
// Transportation fields
|
||||
entity.setTransportationType(rs.getString("transportation_type"));
|
||||
entity.setHuPerLayer(rs.getInt("hu_per_layer"));
|
||||
entity.setContainerType(ContainerType.valueOf(rs.getString("container_type")));
|
||||
entity.setHuCount(rs.getInt("hu_count"));
|
||||
entity.setLayerStructure(rs.getString("layer_structure"));
|
||||
entity.setLayerCount(rs.getInt("layer_count"));
|
||||
entity.setTransportWeightExceeded(rs.getBoolean("transport_weight_exceeded"));
|
||||
entity.setTransportsPerYear(rs.getBigDecimal("transports_per_year"));
|
||||
entity.setShippingFrequency(rs.getInt("shipping_frequency"));
|
||||
entity.setAnnualTransportationCost(rs.getBigDecimal("annual_transportation_cost"));
|
||||
|
||||
// Material Cost fields
|
||||
|
|
|
|||
|
|
@ -21,6 +21,23 @@ public class CalculationJobRepository {
|
|||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Integer insert(CalculationJob job) {
|
||||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<CalculationJob> getCalculationJob(Integer id) {
|
||||
String query = "SELECT * FROM calculation_job WHERE id = ?";
|
||||
|
||||
var job = jdbcTemplate.query(query, new CalculationJobMapper(), id);
|
||||
|
||||
if(job.isEmpty())
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.of(job.getFirst());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<CalculationJob> getCalculationJob(Integer periodId, Integer nodeId, Integer materialId) {
|
||||
|
||||
|
|
@ -49,7 +66,6 @@ public class CalculationJobRepository {
|
|||
entity.setPropertySetId(rs.getInt("property_set_id"));
|
||||
entity.setUserId(rs.getInt("user_id"));
|
||||
entity.setCalculationDate(rs.getTimestamp("calculation_date").toLocalDateTime());
|
||||
entity.setWeightedTotalCosts(rs.getBigDecimal("weighted_total_costs"));
|
||||
|
||||
return entity;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,17 @@ package de.avatic.lcc.repositories.calculation;
|
|||
|
||||
import de.avatic.lcc.dto.generic.TransportType;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobRouteSection;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.*;
|
||||
|
||||
@Repository
|
||||
|
|
@ -20,6 +24,56 @@ public class CalculationJobRouteSectionRepository {
|
|||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Integer insert(CalculationJobRouteSection section) {
|
||||
KeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
|
||||
String query = """
|
||||
INSERT INTO calculation_job_route_section (
|
||||
premise_route_section_id,
|
||||
calculation_job_destination_id,
|
||||
transport_type,
|
||||
is_unmixed_price,
|
||||
is_cbm_price,
|
||||
is_weight_price,
|
||||
is_stacked,
|
||||
is_pre_run,
|
||||
is_main_run,
|
||||
is_post_run,
|
||||
rate,
|
||||
distance,
|
||||
cbm_price,
|
||||
weight_price,
|
||||
annual_cost,
|
||||
transit_time
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
""";
|
||||
|
||||
jdbcTemplate.update(connection -> {
|
||||
var ps = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
|
||||
ps.setInt(1, section.getPremiseRouteSectionId());
|
||||
ps.setInt(2, section.getCalculationJobDestinationId());
|
||||
ps.setString(3, section.getTransportType().name());
|
||||
ps.setBoolean(4, section.getUnmixedPrice());
|
||||
ps.setBoolean(5, section.isCbmPrice());
|
||||
ps.setBoolean(6, section.isWeightPrice());
|
||||
ps.setBoolean(7, section.getStacked());
|
||||
ps.setBoolean(8, section.getPreRun());
|
||||
ps.setBoolean(9, section.getMainRun());
|
||||
ps.setBoolean(10, section.getPostRun());
|
||||
ps.setBigDecimal(11, section.getRate());
|
||||
ps.setBigDecimal(12, section.getDistance());
|
||||
ps.setBigDecimal(13, section.getCbmPrice());
|
||||
ps.setBigDecimal(14, section.getWeightPrice());
|
||||
ps.setBigDecimal(15, section.getAnnualCost());
|
||||
ps.setInt(16, section.getTransitTime());
|
||||
return ps;
|
||||
}, keyHolder);
|
||||
|
||||
return keyHolder.getKey() != null ? keyHolder.getKey().intValue() : null;
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public List<CalculationJobRouteSection> getRouteSectionsByDestinationId(Integer destinationId) {
|
||||
String query = "SELECT * FROM calculation_job_route_section WHERE calculation_job_destination_id = ?";
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.springframework.jdbc.core.RowMapper;
|
|||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
|
@ -23,6 +24,7 @@ public class DestinationRepository {
|
|||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<Destination> getById(Integer id) {
|
||||
String query = "SELECT * FROM premise_destination WHERE id = ?";
|
||||
|
||||
|
|
@ -35,18 +37,21 @@ public class DestinationRepository {
|
|||
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<Destination> getByPremiseId(Integer id) {
|
||||
String query = "SELECT * FROM premise_destination WHERE premise_id = ?";
|
||||
|
||||
return jdbcTemplate.query(query, new DestinationMapper(), id);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void update(Integer id, Integer userId, Number repackingCost, Number disposalCost, Number handlingCost) {
|
||||
String query = "UPDATE premise_destination SET repacking_cost = ?, disposal_cost = ?, handling_cost = ? WHERE id = ? AND user_id = ?";
|
||||
//TODO
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public void deleteById(Integer id) {
|
||||
if (id == null) {
|
||||
return;
|
||||
|
|
@ -56,6 +61,7 @@ public class DestinationRepository {
|
|||
jdbcTemplate.update(sql, id);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<Integer> getOwnerIdById(Integer id) {
|
||||
String query = """
|
||||
SELECT p.user_id AS user_id
|
||||
|
|
@ -73,6 +79,7 @@ public class DestinationRepository {
|
|||
return Optional.of(userId.getFirst());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<Destination> getByPremiseIdsAndNodeId(List<Integer> premiseId, Integer nodeId, Integer userId) {
|
||||
String placeholder = String.join(",", Collections.nCopies(premiseId.size(), "?"));
|
||||
String query = "SELECT * FROM premise_destination JOIN premise ON premise_destination.premise_id = premise.id WHERE premise_id IN ("+placeholder+") AND premise_destination.destination_node_id AND premise.user_id = ?";
|
||||
|
|
@ -80,10 +87,11 @@ public class DestinationRepository {
|
|||
return jdbcTemplate.query(query, new DestinationMapper(), premiseId, nodeId, userId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Integer insert(Destination destination) {
|
||||
KeyHolder keyHolder = new GeneratedKeyHolder();
|
||||
|
||||
String query = "INSERT INTO premise_destination (annual_amount, premise_id, destination_node_id, rate_d2d, is_d2d, repacking_cost, handling_cost, disposal_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
String query = "INSERT INTO premise_destination (annual_amount, premise_id, destination_node_id, rate_d2d, lead_time_d2d, is_d2d, repacking_cost, handling_cost, disposal_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
jdbcTemplate.update(connection -> {
|
||||
var ps = connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
|
||||
|
|
@ -91,16 +99,18 @@ public class DestinationRepository {
|
|||
ps.setInt(2, destination.getPremiseId());
|
||||
ps.setInt(3, destination.getDestinationNodeId());
|
||||
ps.setBigDecimal(4, destination.getRateD2d());
|
||||
ps.setBoolean(5, destination.getD2d());
|
||||
ps.setBigDecimal(6, destination.getRepackingCost());
|
||||
ps.setBigDecimal(7, destination.getHandlingCost());
|
||||
ps.setBigDecimal(8, destination.getDisposalCost());
|
||||
ps.setInt(5, destination.getLeadTimeD2d());
|
||||
ps.setBoolean(6, destination.getD2d());
|
||||
ps.setBigDecimal(7, destination.getRepackingCost());
|
||||
ps.setBigDecimal(8, destination.getHandlingCost());
|
||||
ps.setBigDecimal(9, destination.getDisposalCost());
|
||||
return ps;
|
||||
}, keyHolder);
|
||||
|
||||
return keyHolder.getKey() != null ? keyHolder.getKey().intValue() : null;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void duplicate(Integer fromId, Integer toId) {
|
||||
|
||||
}
|
||||
|
|
@ -117,6 +127,7 @@ public class DestinationRepository {
|
|||
entity.setDestinationNodeId(rs.getInt("destination_node_id"));
|
||||
entity.setRateD2d(rs.getBigDecimal("rate_d2d"));
|
||||
entity.setD2d(rs.getBoolean("is_d2d"));
|
||||
entity.setLeadTimeD2d(rs.getInt("lead_time_d2d"));
|
||||
entity.setRepackingCost(rs.getBigDecimal("repacking_cost"));
|
||||
entity.setHandlingCost(rs.getBigDecimal("handling_cost"));
|
||||
entity.setDisposalCost(rs.getBigDecimal("disposal_cost"));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package de.avatic.lcc.repositories.properties;
|
|||
|
||||
|
||||
import de.avatic.lcc.model.properties.PropertySet;
|
||||
import de.avatic.lcc.model.rates.ValidityPeriod;
|
||||
import de.avatic.lcc.model.rates.ValidityPeriodState;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
|
@ -73,6 +74,15 @@ public class PropertySetRepository {
|
|||
return jdbcTemplate.queryForObject("SELECT id, start_date, end_date, state FROM property_set WHERE state = ?", new PropertySetMapper(), ValidityPeriodState.VALID.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the currently valid property set id.
|
||||
*
|
||||
* @return the ID of the valid {@link PropertySet}.
|
||||
*/
|
||||
public Integer getValidSetId() {
|
||||
return getValidSet().getId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies the draft property set, marking it as valid and expiring the current valid set.
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ public class ContainerRateRepository {
|
|||
return Optional.of(route.getFirst());
|
||||
}
|
||||
|
||||
|
||||
private static class ContainerRateMapper implements RowMapper<ContainerRate> {
|
||||
|
||||
private final boolean fetchCountryIds;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import org.springframework.stereotype.Service;
|
|||
|
||||
@Service
|
||||
public class CustomApiService {
|
||||
public Number getTariffRate(String hsCode, Integer countryId) {
|
||||
return null;
|
||||
public Double getTariffRate(String hsCode, Integer countryId) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,10 +71,11 @@ public class DestinationService {
|
|||
destination.setPremiseId(premise.getId());
|
||||
destination.setAnnualAmount(0);
|
||||
destination.setD2d(false);
|
||||
destination.setLeadTimeD2d(0);
|
||||
destination.setRateD2d(BigDecimal.ZERO);
|
||||
destination.setDisposalCost(null);
|
||||
destination.setHandlingCost(null);
|
||||
destination.setRepackingCost(null);
|
||||
destination.setRateD2d(BigDecimal.ZERO);
|
||||
destination.setId(destinationRepository.insert(destination));
|
||||
destination.setGeoLat(destinationNode.getGeoLat());
|
||||
destination.setGeoLng(destinationNode.getGeoLng());
|
||||
|
|
|
|||
|
|
@ -1,19 +1,29 @@
|
|||
package de.avatic.lcc.service.access;
|
||||
|
||||
import de.avatic.lcc.dto.bulk.BulkStatus;
|
||||
import de.avatic.lcc.dto.calculation.CalculationStatus;
|
||||
import de.avatic.lcc.dto.calculation.PremiseDTO;
|
||||
import de.avatic.lcc.dto.calculation.edit.PremiseDetailDTO;
|
||||
import de.avatic.lcc.dto.calculation.edit.masterData.MaterialUpdateDTO;
|
||||
import de.avatic.lcc.dto.calculation.edit.masterData.PackagingUpdateDTO;
|
||||
import de.avatic.lcc.dto.calculation.edit.masterData.PriceUpdateDTO;
|
||||
import de.avatic.lcc.model.calculations.CalculationJob;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobState;
|
||||
import de.avatic.lcc.repositories.calculation.CalculationJobRepository;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import de.avatic.lcc.repositories.premise.PremiseRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertySetRepository;
|
||||
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
|
||||
import de.avatic.lcc.service.calculation.execution.CalculationStatusService;
|
||||
import de.avatic.lcc.service.transformer.generic.DimensionTransformer;
|
||||
import de.avatic.lcc.service.transformer.premise.PremiseTransformer;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -24,12 +34,22 @@ public class PremisesService {
|
|||
private final PremiseTransformer premiseTransformer;
|
||||
private final DimensionTransformer dimensionTransformer;
|
||||
private final DestinationService destinationService;
|
||||
private final CalculationJobRepository calculationJobRepository;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final PropertySetRepository propertySetRepository;
|
||||
private final ValidityPeriodRepository validityPeriodRepository;
|
||||
private final CalculationStatusService calculationStatusService;
|
||||
|
||||
public PremisesService(PremiseRepository premiseRepository, PremiseTransformer premiseTransformer, DimensionTransformer dimensionTransformer, DestinationService destinationService) {
|
||||
public PremisesService(PremiseRepository premiseRepository, PremiseTransformer premiseTransformer, DimensionTransformer dimensionTransformer, DestinationService destinationService, CalculationJobRepository calculationJobRepository, PropertyRepository propertyRepository, PropertySetRepository propertySetRepository, ValidityPeriodRepository validityPeriodRepository, CalculationStatusService calculationStatusService) {
|
||||
this.premiseRepository = premiseRepository;
|
||||
this.premiseTransformer = premiseTransformer;
|
||||
this.dimensionTransformer = dimensionTransformer;
|
||||
this.destinationService = destinationService;
|
||||
this.calculationJobRepository = calculationJobRepository;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.propertySetRepository = propertySetRepository;
|
||||
this.validityPeriodRepository = validityPeriodRepository;
|
||||
this.calculationStatusService = calculationStatusService;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
|
|
@ -50,9 +70,34 @@ public class PremisesService {
|
|||
}
|
||||
|
||||
|
||||
//TODO move to other service
|
||||
|
||||
public Integer startCalculation(List<Integer> premises) {
|
||||
return null;
|
||||
|
||||
var userId = 1; // TODO get current user id
|
||||
|
||||
var validSetId = propertySetRepository.getValidSetId();
|
||||
var validPeriodId = validityPeriodRepository.getValidPeriodId();
|
||||
|
||||
var calculationIds = new ArrayList<>();
|
||||
|
||||
premises.forEach(p -> {
|
||||
CalculationJob job = new CalculationJob();
|
||||
|
||||
job.setPremiseId(p);
|
||||
job.setJobState(CalculationJobState.CREATED);
|
||||
job.setCalculationDate(java.time.LocalDateTime.now());
|
||||
job.setUserId(userId);
|
||||
job.setPropertySetId(validSetId);
|
||||
job.setValidityPeriodId(validPeriodId);
|
||||
|
||||
calculationIds.add(calculationJobRepository.insert(job));
|
||||
});
|
||||
|
||||
return calculationStatusService.schedule(calculationIds);
|
||||
}
|
||||
|
||||
public CalculationStatus getCalculationStatus(Integer processId) {
|
||||
return calculationStatusService.getCalculationStatus(processId);
|
||||
}
|
||||
|
||||
public HashMap<String, String> updatePackaging(PackagingUpdateDTO packagingDTO) {
|
||||
|
|
@ -92,4 +137,5 @@ public class PremisesService {
|
|||
destinationService.deleteAllDestinationsByPremiseId(premiseIds, false);
|
||||
premiseRepository.deletePremisesById(premiseIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,13 +22,15 @@ public class BulkFileProcessingService {
|
|||
private final MaterialExcelMapper materialExcelMapper;
|
||||
private final PackagingExcelMapper packagingExcelMapper;
|
||||
private final NodeExcelMapper nodeExcelMapper;
|
||||
private final BulkStatusService bulkStatusService;
|
||||
|
||||
public BulkFileProcessingService(MatrixRateExcelMapper matrixRateExcelMapper, ContainerRateExcelMapper containerRateExcelMapper, MaterialExcelMapper materialExcelMapper, PackagingExcelMapper packagingExcelMapper, NodeExcelMapper nodeExcelMapper) {
|
||||
public BulkFileProcessingService(MatrixRateExcelMapper matrixRateExcelMapper, ContainerRateExcelMapper containerRateExcelMapper, MaterialExcelMapper materialExcelMapper, PackagingExcelMapper packagingExcelMapper, NodeExcelMapper nodeExcelMapper, BulkStatusService bulkStatusService) {
|
||||
this.matrixRateExcelMapper = matrixRateExcelMapper;
|
||||
this.containerRateExcelMapper = containerRateExcelMapper;
|
||||
this.materialExcelMapper = materialExcelMapper;
|
||||
this.packagingExcelMapper = packagingExcelMapper;
|
||||
this.nodeExcelMapper = nodeExcelMapper;
|
||||
this.bulkStatusService = bulkStatusService;
|
||||
}
|
||||
|
||||
public Integer processFile(BulkFileType type, BulkProcessingType processingType, MultipartFile file) {
|
||||
|
|
@ -75,6 +77,6 @@ public class BulkFileProcessingService {
|
|||
}
|
||||
|
||||
public BulkStatus getStatus(Integer id) {
|
||||
return null;
|
||||
bulkStatusService.getStatus(id);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
package de.avatic.lcc.service.bulk;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class BulkStatusService {
|
||||
|
||||
public void getStatus(Integer id) {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
package de.avatic.lcc.service.calculation;
|
||||
|
||||
import de.avatic.lcc.model.country.Country;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||
import de.avatic.lcc.repositories.country.CountryRepository;
|
||||
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.premise.RouteSectionRepository;
|
||||
import de.avatic.lcc.service.calculation.steps.CustomCostCalculationService;
|
||||
import de.avatic.lcc.service.calculation.steps.RouteSectionCostCalculationService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class CalculationExecutionService {
|
||||
|
||||
|
||||
private final PremiseRepository premiseRepository;
|
||||
private final DestinationRepository destinationRepository;
|
||||
private final RouteRepository routeRepository;
|
||||
private final RouteSectionRepository routeSectionRepository;
|
||||
private final CustomCostCalculationService customCostCalculationService;
|
||||
private final CountryRepository countryRepository;
|
||||
private final RouteSectionCostCalculationService routeSectionCostCalculationService;
|
||||
|
||||
public CalculationExecutionService(PremiseRepository premiseRepository, DestinationRepository destinationRepository, RouteRepository routeRepository, RouteSectionRepository routeSectionRepository, CustomCostCalculationService customCostCalculationService, CountryRepository countryRepository, RouteSectionCostCalculationService routeSectionCostCalculationService) {
|
||||
this.premiseRepository = premiseRepository;
|
||||
this.destinationRepository = destinationRepository;
|
||||
this.routeRepository = routeRepository;
|
||||
this.routeSectionRepository = routeSectionRepository;
|
||||
this.customCostCalculationService = customCostCalculationService;
|
||||
this.countryRepository = countryRepository;
|
||||
this.routeSectionCostCalculationService = routeSectionCostCalculationService;
|
||||
}
|
||||
|
||||
public void doCalculation(Integer premiseId) {
|
||||
Premise premise = premiseRepository.getPremiseById(premiseId).orElseThrow();
|
||||
|
||||
List<Destination> destinations = destinationRepository.getByPremiseId(premiseId);
|
||||
destinations.forEach(destination -> doDestinationCalculation(destination, premise));
|
||||
|
||||
}
|
||||
|
||||
private void doDestinationCalculation(Destination destination, Premise premise) {
|
||||
var route = routeRepository.getSelectedByDestinationId(destination.getId()).orElseThrow();
|
||||
List<RouteSection> section = routeSectionRepository.getByRouteId(route.getId());
|
||||
|
||||
routeSectionCostCalculationService.doCalculation();
|
||||
|
||||
Country supplierCountry = countryRepository.getById(premise.getCountryId()).orElseThrow();
|
||||
Country destinationCountry = countryRepository.getById(destination.getCountryId()).orElseThrow();
|
||||
customCostCalculationService.doCalculation(premise.getHsCode(), supplierCountry, destinationCountry, route, section);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
package de.avatic.lcc.service.calculation.execution;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.*;
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
import de.avatic.lcc.dto.generic.RateType;
|
||||
import de.avatic.lcc.model.calculations.CalculationJob;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobDestination;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobRouteSection;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobState;
|
||||
import de.avatic.lcc.model.packaging.LoadCarrierType;
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.repositories.calculation.CalculationJobDestinationRepository;
|
||||
import de.avatic.lcc.repositories.calculation.CalculationJobRepository;
|
||||
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.premise.RouteSectionRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.service.calculation.execution.steps.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class CalculationExecutionService {
|
||||
|
||||
|
||||
private final PremiseRepository premiseRepository;
|
||||
private final DestinationRepository destinationRepository;
|
||||
private final RouteRepository routeRepository;
|
||||
private final RouteSectionRepository routeSectionRepository;
|
||||
private final CustomCostCalculationService customCostCalculationService;
|
||||
private final RouteSectionCostCalculationService routeSectionCostCalculationService;
|
||||
private final HandlingCostCalculationService handlingCostCalculationService;
|
||||
private final InventoryCostCalculationService inventoryCostCalculationService;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final AirfreightCalculationService airfreightCalculationService;
|
||||
private final PremiseToHuService premiseToHuService;
|
||||
private final ContainerCalculationService containerCalculationService;
|
||||
private final ShippingFrequencyCalculationService shippingFrequencyCalculationService;
|
||||
private final CalculationJobRepository calculationJobRepository;
|
||||
private final CalculationJobDestinationRepository calculationJobDestinationRepository;
|
||||
|
||||
public CalculationExecutionService(PremiseRepository premiseRepository, DestinationRepository destinationRepository, RouteRepository routeRepository, RouteSectionRepository routeSectionRepository, CustomCostCalculationService customCostCalculationService, RouteSectionCostCalculationService routeSectionCostCalculationService, HandlingCostCalculationService handlingCostCalculationService, InventoryCostCalculationService inventoryCostCalculationService, PropertyRepository propertyRepository, AirfreightCalculationService airfreightCalculationService, PremiseToHuService premiseToHuService, ContainerCalculationService containerCalculationService, ShippingFrequencyCalculationService shippingFrequencyCalculationService, CalculationJobRepository calculationJobRepository, CalculationJobDestinationRepository calculationJobDestinationRepository) {
|
||||
this.premiseRepository = premiseRepository;
|
||||
this.destinationRepository = destinationRepository;
|
||||
this.routeRepository = routeRepository;
|
||||
this.routeSectionRepository = routeSectionRepository;
|
||||
this.customCostCalculationService = customCostCalculationService;
|
||||
this.routeSectionCostCalculationService = routeSectionCostCalculationService;
|
||||
this.handlingCostCalculationService = handlingCostCalculationService;
|
||||
this.inventoryCostCalculationService = inventoryCostCalculationService;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.airfreightCalculationService = airfreightCalculationService;
|
||||
this.premiseToHuService = premiseToHuService;
|
||||
this.containerCalculationService = containerCalculationService;
|
||||
this.shippingFrequencyCalculationService = shippingFrequencyCalculationService;
|
||||
this.calculationJobRepository = calculationJobRepository;
|
||||
this.calculationJobDestinationRepository = calculationJobDestinationRepository;
|
||||
}
|
||||
|
||||
private static ContainerType getBestContainerType(Map<ContainerType, List<SectionInfo>> sectionResults) {
|
||||
return sectionResults.entrySet().stream()
|
||||
.min(Comparator.comparing(entry ->
|
||||
entry.getValue().stream()
|
||||
.map(SectionInfo::result)
|
||||
.map(CalculationJobRouteSection::getAnnualCost)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add)))
|
||||
.map(Map.Entry::getKey)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public void calculateJob(Integer calculationId) {
|
||||
|
||||
CalculationJob calculation = calculationJobRepository.getCalculationJob(calculationId).orElseThrow();
|
||||
|
||||
if(CalculationJobState.SCHEDULED.equals(calculation.getJobState())) {
|
||||
Premise premise = premiseRepository.getPremiseById(calculation.getId()).orElseThrow();
|
||||
|
||||
// material cost + fca cost
|
||||
var materialCost = premise.getMaterialCost();
|
||||
BigDecimal fcaFee;
|
||||
|
||||
if (premise.getFcaEnabled()) {
|
||||
var fcaProperty = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FCA_FEE).orElseThrow();
|
||||
var fcaShare = Double.parseDouble(fcaProperty.getCurrentValue());
|
||||
fcaFee = BigDecimal.valueOf(fcaShare).multiply(materialCost);
|
||||
} else {
|
||||
fcaFee = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
List<Destination> destinations = destinationRepository.getByPremiseId(premise.getId());
|
||||
var destinationInfos = destinations.stream().map(destination -> doDestinationCalculation(destination, premise, materialCost, fcaFee)).toList();
|
||||
|
||||
calculationJobDestinationRepository.createDestination(destinationInfos);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private DestinationInfo doDestinationCalculation(Destination destination, Premise premise, BigDecimal materialCost, BigDecimal fcaFee) {
|
||||
|
||||
InventoryCostResult inventoryCost;
|
||||
HandlingResult handlingCost;
|
||||
CustomResult customCost;
|
||||
List<SectionInfo> sections;
|
||||
AirfreightResult airfreightCost = airfreightCalculationService.doCalculation(premise, destination);
|
||||
|
||||
CalculationJobDestination destinationCalculationJob = new CalculationJobDestination();
|
||||
|
||||
if (destination.getD2d()) {
|
||||
|
||||
// Get container calculation
|
||||
PackagingDimension hu = premiseToHuService.createHuFromPremise(premise);
|
||||
var containerCalculation = containerCalculationService.doCalculation(hu, ContainerType.FEU);
|
||||
|
||||
var routeCost = routeSectionCostCalculationService.doD2dCalculation(premise, destination, containerCalculation);
|
||||
handlingCost = handlingCostCalculationService.doCalculation(premise, destination, true);
|
||||
inventoryCost = inventoryCostCalculationService.doCalculation(premise, destination, BigDecimal.valueOf(destination.getLeadTimeD2d()));
|
||||
customCost = customCostCalculationService.doD2dCalculation(premise, destination, routeCost);
|
||||
sections = List.of(new SectionInfo(null, routeCost, containerCalculation));
|
||||
|
||||
destinationCalculationJob.setContainerType(ContainerType.FEU);
|
||||
|
||||
} else {
|
||||
var route = routeRepository.getSelectedByDestinationId(destination.getId()).orElseThrow();
|
||||
List<RouteSection> routeSections = routeSectionRepository.getByRouteId(route.getId());
|
||||
|
||||
Map<ContainerType, List<SectionInfo>> sectionInfos = new HashMap<>();
|
||||
Map<ContainerType, ContainerCalculationResult> containerCalculation = new HashMap<>();
|
||||
|
||||
// Get container calculation
|
||||
PackagingDimension hu = premiseToHuService.createHuFromPremise(premise);
|
||||
Arrays.stream(ContainerType.values()).forEach(type -> containerCalculation.put(type, containerCalculationService.doCalculation(hu, type)));
|
||||
|
||||
Arrays.stream(ContainerType.values()).forEach(type -> sectionInfos.put(type, routeSections.stream().map(s -> new SectionInfo(s, doSectionCalculation(premise, destination, s, type, containerCalculation), containerCalculation.get(type))).toList()));
|
||||
ContainerType bestContainerType = getBestContainerType(sectionInfos);
|
||||
|
||||
customCost = customCostCalculationService.doCalculation(premise, destination, sectionInfos.get(bestContainerType));
|
||||
handlingCost = handlingCostCalculationService.doCalculation(premise, destination, sectionInfos.get(bestContainerType).stream().anyMatch(s -> s.section().getMainRun()));
|
||||
inventoryCost = inventoryCostCalculationService.doCalculation(premise, destination, BigDecimal.valueOf(sectionInfos.get(bestContainerType).stream().mapToInt(s -> s.result().getTransitTime()).sum()));
|
||||
sections = sectionInfos.get(bestContainerType);
|
||||
|
||||
destinationCalculationJob.setContainerType(bestContainerType);
|
||||
|
||||
}
|
||||
|
||||
destinationCalculationJob.setMaterialCost(materialCost);
|
||||
destinationCalculationJob.setFcaCost(fcaFee);
|
||||
|
||||
destinationCalculationJob.setAirFreightShare(airfreightCost.getAirFreightShare());
|
||||
destinationCalculationJob.setAirFreightShareMax(airfreightCost.getMaxAirfreightShare());
|
||||
destinationCalculationJob.setAirFreightWeight(airfreightCost.getWeight());
|
||||
destinationCalculationJob.setAirFreightVolumetricWeight(airfreightCost.getVolumetricWeight());
|
||||
destinationCalculationJob.setAnnualAirFreightCost(airfreightCost.getAnnualCost());
|
||||
|
||||
destinationCalculationJob.setSmallUnit(handlingCost.getLoadCarrierType().equals(LoadCarrierType.SLC));
|
||||
destinationCalculationJob.setAnnualHandlingCost(handlingCost.getAnnualHandlingCost());
|
||||
destinationCalculationJob.setAnnualRepackingCost(handlingCost.getAnnualRepackingCost());
|
||||
destinationCalculationJob.setAnnualDisposalCost(handlingCost.getAnnualDisposalCost());
|
||||
|
||||
destinationCalculationJob.setStockedInventory(inventoryCost.getStockedInventory());
|
||||
destinationCalculationJob.setInTransportStock(inventoryCost.getInTransportStock());
|
||||
destinationCalculationJob.setSafetyStockInDays(inventoryCost.getSafetyStockInDays());
|
||||
destinationCalculationJob.setSafetyStock(inventoryCost.getSafetyStock());
|
||||
destinationCalculationJob.setStockBeforePayment(inventoryCost.getStockBeforePayment());
|
||||
destinationCalculationJob.setOperationalStock(inventoryCost.getOperationalStock());
|
||||
destinationCalculationJob.setAnnualCapitalCost(inventoryCost.getAnnualCapitalCost());
|
||||
destinationCalculationJob.setAnnualStorageCost(inventoryCost.getAnnualStorageCost());
|
||||
|
||||
destinationCalculationJob.setCustomDuties(customCost.getCustomDuties());
|
||||
destinationCalculationJob.setCustomValue(customCost.getCustomValue());
|
||||
destinationCalculationJob.setTariffRate(customCost.getTariffRate());
|
||||
destinationCalculationJob.setAnnualCustomCost(customCost.getAnnualCost());
|
||||
|
||||
destinationCalculationJob.setAnnualTransportationCost(sections.stream().map(SectionInfo::result).map(CalculationJobRouteSection::getAnnualCost).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
destinationCalculationJob.setTransportWeightExceeded(sections.stream().map(SectionInfo::result).anyMatch(CalculationJobRouteSection::isWeightPrice));
|
||||
destinationCalculationJob.setLayerCount(sections.getFirst().containerResult().getLayer());
|
||||
destinationCalculationJob.setLayerStructure(null); //TODO generate layer structure
|
||||
destinationCalculationJob.setHuCount(sections.getFirst().containerResult().getHuUnitCount());
|
||||
|
||||
destinationCalculationJob.setAnnualAmount(BigDecimal.valueOf(destination.getAnnualAmount()));
|
||||
destinationCalculationJob.setShippingFrequency(shippingFrequencyCalculationService.doCalculation(destination.getAnnualAmount()));
|
||||
|
||||
var commonCost = destinationCalculationJob.getAnnualHandlingCost()
|
||||
.add(destinationCalculationJob.getAnnualDisposalCost())
|
||||
.add(destinationCalculationJob.getAnnualCapitalCost())
|
||||
.add(destinationCalculationJob.getAnnualStorageCost())
|
||||
.add(materialCost)
|
||||
.add(fcaFee);
|
||||
|
||||
var totalCost = commonCost.add(destinationCalculationJob.getAnnualTransportationCost()).add(destinationCalculationJob.getAnnualCustomCost());
|
||||
var totalRiskCost = commonCost.add(customCost.getAnnualRiskCost()).add(sections.stream().map(SectionInfo::result).map(CalculationJobRouteSection::getAnnualRiskCost).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
var totalChanceCost = commonCost.add(customCost.getAnnualChanceCost()).add(sections.stream().map(SectionInfo::result).map(CalculationJobRouteSection::getAnnualChanceCost).reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
|
||||
destinationCalculationJob.setTotalCost(totalCost);
|
||||
destinationCalculationJob.setTotalRiskCost(totalRiskCost);
|
||||
destinationCalculationJob.setTotalChanceCost(totalChanceCost);
|
||||
|
||||
return new DestinationInfo(destination, destinationCalculationJob, sections);
|
||||
}
|
||||
|
||||
private CalculationJobRouteSection doSectionCalculation(Premise premise, Destination destination, RouteSection section, ContainerType containerType, Map<ContainerType, ContainerCalculationResult> calculationResult) {
|
||||
if (RateType.MATRIX == section.getRateType()) {
|
||||
return routeSectionCostCalculationService.doCalculation(premise, destination, section, calculationResult.get(ContainerType.TRUCK));
|
||||
} else {
|
||||
return routeSectionCostCalculationService.doCalculation(premise, destination, section, calculationResult.get(containerType));
|
||||
}
|
||||
}
|
||||
|
||||
private record DestinationInfo(Destination destination, CalculationJobDestination destinationCalculationJob,
|
||||
List<SectionInfo> sectionInfo) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package de.avatic.lcc.service.calculation.execution;
|
||||
|
||||
import de.avatic.lcc.dto.calculation.CalculationStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Service
|
||||
public class CalculationStatusService {
|
||||
|
||||
AtomicReference<HashMap<Integer, CalculationStatus>> status = new AtomicReference<>();
|
||||
|
||||
public CalculationStatus getCalculationStatus(int processId) {
|
||||
return status.get().get(processId);
|
||||
}
|
||||
|
||||
public void addCalculationStatus(int statusId, CalculationStatus calculationStatus) {
|
||||
HashMap<Integer, CalculationStatus> map = status.get();
|
||||
if(map == null){
|
||||
map = new HashMap<>();
|
||||
}
|
||||
map.put(statusId, calculationStatus);
|
||||
status.set(map);
|
||||
}
|
||||
|
||||
public void removeCalculationStatus(int statusId) {
|
||||
HashMap<Integer, CalculationStatus> map = status.get();
|
||||
if(map != null){
|
||||
map.remove(statusId);
|
||||
}
|
||||
}
|
||||
|
||||
public Integer schedule(ArrayList<Object> calculationIds) {
|
||||
//TODO
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.AirfreightResult;
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.properties.CountryPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.utils.DimensionUnit;
|
||||
import de.avatic.lcc.model.utils.WeightUnit;
|
||||
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
public class AirfreightCalculationService {
|
||||
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final PremiseToHuService premiseToHuService;
|
||||
private final CountryPropertyRepository countryPropertyRepository;
|
||||
|
||||
public AirfreightCalculationService(PropertyRepository propertyRepository, PremiseToHuService premiseToHuService, CountryPropertyRepository countryPropertyRepository) {
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.premiseToHuService = premiseToHuService;
|
||||
this.countryPropertyRepository = countryPropertyRepository;
|
||||
}
|
||||
|
||||
public AirfreightResult doCalculation(Premise premise, Destination destination) {
|
||||
|
||||
var maxAirfreightShare = Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.AIR_SHARE, 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 result = new AirfreightResult();
|
||||
|
||||
var huCost = BigDecimal.valueOf(1.08).multiply(((getShippingWeight(hu).multiply(preCarriage.add(mainCarriage).add(postCarriage).add(terminalFee))).add(preCarriageFee).add(customsClearanceFee).add(handOverFee)));
|
||||
var totalCost = huCost.multiply(BigDecimal.valueOf(destination.getAnnualAmount()).divide(BigDecimal.valueOf(premise.getHuUnitCount())));
|
||||
var airfreightShareCost = totalCost.multiply(BigDecimal.valueOf(airfreightShare));
|
||||
|
||||
result.setVolumetricWeight(BigDecimal.valueOf(getVolumeWeight(hu)));
|
||||
result.setWeight(BigDecimal.valueOf(getWeightInKg(hu)));
|
||||
result.setMaxAirfreightShare(BigDecimal.valueOf(maxAirfreightShare));
|
||||
result.setAirFreightShare(BigDecimal.valueOf(airfreightShare));
|
||||
result.setAnnualCost(airfreightShareCost);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private BigDecimal getShippingWeight(PackagingDimension hu) {
|
||||
return BigDecimal.valueOf(Math.max(getWeightInKg(hu), getVolumeWeight(hu)));
|
||||
}
|
||||
|
||||
private double getVolumeWeight(PackagingDimension hu) {
|
||||
return 0.0002 * getDimensionInCm(hu.getLength(), hu.getDimensionUnit()) * getDimensionInCm(hu.getWidth(), hu.getDimensionUnit()) * getDimensionInCm(hu.getHeight(), hu.getDimensionUnit());
|
||||
}
|
||||
|
||||
private double getDimensionInCm(Number dimension, DimensionUnit unit) {
|
||||
return DimensionUnit.CM.convertFromMM(dimension).doubleValue();
|
||||
}
|
||||
|
||||
private double getWeightInKg(PackagingDimension hu) {
|
||||
return WeightUnit.KG.convertFromG(hu.getWeight()).doubleValue();
|
||||
}
|
||||
|
||||
private double getAirfreightShare(double maxAirfreightShare, double overseaShare) {
|
||||
|
||||
// Ensure oversea share is within valid range
|
||||
if (overseaShare < 0 || overseaShare > 100) {
|
||||
throw new IllegalArgumentException("Oversea share must be between 0 and 100");
|
||||
}
|
||||
|
||||
// First segment: from (0,0) to (50, 20% of max)
|
||||
if (overseaShare <= 50) {
|
||||
// Linear interpolation: y = mx + b
|
||||
// m = (0.2 * maxAirfreightShare - 0) / (50 - 0) = 0.004 * maxAirfreightShare
|
||||
// b = 0
|
||||
return (0.004 * maxAirfreightShare * overseaShare);
|
||||
}
|
||||
// Second segment: from (50, 20% of max) to (100, max)
|
||||
else {
|
||||
// Linear interpolation: y = mx + b
|
||||
// m = (maxAirfreightShare - 0.2 * maxAirfreightShare) / (100 - 50) = 0.016 * maxAirfreightShare
|
||||
// b = 0.2 * maxAirfreightShare - 50 * 0.016 * maxAirfreightShare = -0.6 * maxAirfreightShare
|
||||
return (0.016 * maxAirfreightShare * overseaShare - 0.6 * maxAirfreightShare);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.ChangeRiskFactorCalculationResult;
|
||||
import de.avatic.lcc.dto.generic.TransportType;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.rates.ContainerRate;
|
||||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.repositories.rates.ContainerRateRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
public class ChangeRiskFactorCalculationService {
|
||||
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final ContainerRateRepository containerRateRepository;
|
||||
private final NodeRepository nodeRepository;
|
||||
|
||||
public ChangeRiskFactorCalculationService(PropertyRepository propertyRepository, ContainerRateRepository containerRateRepository, NodeRepository nodeRepository) {
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.containerRateRepository = containerRateRepository;
|
||||
this.nodeRepository = nodeRepository;
|
||||
}
|
||||
|
||||
public ChangeRiskFactorCalculationResult getChanceRiskFactors() {
|
||||
var rate = findRate();
|
||||
var riskValue = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.RISK_REF).orElseThrow().getCurrentValue());
|
||||
var chanceValue = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CHANCE_REF).orElseThrow().getCurrentValue());
|
||||
|
||||
var result = new ChangeRiskFactorCalculationResult();
|
||||
result.setChanceFactor(rate.getRateFeu().divide(BigDecimal.valueOf(chanceValue), 2, RoundingMode.HALF_UP));
|
||||
result.setRiskFactor(rate.getRateFeu().divide(BigDecimal.valueOf(riskValue), 2, RoundingMode.HALF_UP));
|
||||
return result;
|
||||
}
|
||||
|
||||
private ContainerRate findRate() {
|
||||
var startReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.START_REF).orElseThrow().getCurrentValue();
|
||||
var endReference = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.END_REF).orElseThrow().getCurrentValue();
|
||||
|
||||
var startNode = nodeRepository.getByExternalMappingId(startReference).orElseThrow();
|
||||
var endNode = nodeRepository.getByExternalMappingId(endReference).orElseThrow();
|
||||
|
||||
return containerRateRepository.findRoute(startNode.getId(), endNode.getId(), TransportType.SEA).orElseThrow();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.ContainerCalculationResult;
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
|
|
@ -23,7 +23,7 @@ public class ContainerCalculationService {
|
|||
this.propertyRepository = propertyRepository;
|
||||
}
|
||||
|
||||
public ContainerCalculationResult doCalculation(PackagingDimension hu, ContainerType containerType) {
|
||||
public ContainerCalculationResult doCalculation(PackagingDimension hu, ContainerType containerType) {
|
||||
|
||||
var weightInKg = WeightUnit.KG.convertFromG(hu.getWeight()).intValue();
|
||||
var maxContainerLoad = getMaxContainerLoad(containerType);
|
||||
|
|
@ -42,9 +42,10 @@ public class ContainerCalculationService {
|
|||
return new ContainerCalculationResult(Math.min(containerType.getPalletCount(PalletType.INDUSTRIAL_PALLET)*layers,maxUnitByWeight), layers, null, containerType.getPalletCount(PalletType.INDUSTRIAL_PALLET) > maxUnitByWeight, containerType, dimensions, maxContainerLoad);
|
||||
}
|
||||
|
||||
return toContainerCalculationResult(bestSolution, layers, maxUnitByWeight, containerType, dimensions, maxContainerLoad);
|
||||
return createContainerCalculationResult(bestSolution, layers, maxUnitByWeight, containerType, dimensions, maxContainerLoad);
|
||||
}
|
||||
|
||||
|
||||
private static Solution solveLayer(PackagingDimension dimension,
|
||||
int containerWidth, int containerLength) {
|
||||
|
||||
|
|
@ -62,10 +63,13 @@ public class ContainerCalculationService {
|
|||
for (int verticalColumnCount = 0; verticalColumnCount <= maxVerticalColumns; verticalColumnCount++) {
|
||||
for (int circularColumnCount = 0; circularColumnCount <= maxCircularColumns; circularColumnCount++) {
|
||||
// Check constraints
|
||||
if (horizontalColumn.getColumnWidth() * horizontalColumnCount
|
||||
+ horizontalColumn.getColumnWidth() * verticalColumnCount
|
||||
+ horizontalColumn.getColumnWidth() * circularColumnCount <= containerLength) {
|
||||
var current = new Solution(horizontalColumnCount, verticalColumnCount, circularColumnCount, horizontalColumn, verticalColumn, circularColumn);
|
||||
if (fitsInContainer(horizontalColumn, verticalColumn, circularColumn,
|
||||
horizontalColumnCount, verticalColumnCount, circularColumnCount, containerLength)) {
|
||||
|
||||
Solution current = new Solution(
|
||||
horizontalColumnCount, verticalColumnCount, circularColumnCount,
|
||||
horizontalColumn, verticalColumn, circularColumn);
|
||||
|
||||
if (current.getTotal() > bestSolution.getTotal()) {
|
||||
bestSolution = current;
|
||||
}
|
||||
|
|
@ -77,38 +81,45 @@ public class ContainerCalculationService {
|
|||
return bestSolution;
|
||||
}
|
||||
|
||||
private static boolean fitsInContainer(Column horizontalColumn, Column verticalColumn, Column circularColumn,
|
||||
int horizontalCount, int verticalCount, int circularCount,
|
||||
int containerLength) {
|
||||
return horizontalColumn.getColumnWidth() * horizontalCount
|
||||
+ verticalColumn.getColumnWidth() * verticalCount
|
||||
+ circularColumn.getColumnWidth() * circularCount <= containerLength;
|
||||
}
|
||||
|
||||
private int getMaxContainerLoad(ContainerType containerType) {
|
||||
Map<ContainerType, SystemPropertyMappingId> mappings = Map.of(
|
||||
ContainerType.FEU, SystemPropertyMappingId.FEU_LOAD,
|
||||
ContainerType.TRUCK, SystemPropertyMappingId.TRUCK_LOAD,
|
||||
ContainerType.TEU, SystemPropertyMappingId.TEU_LOAD
|
||||
);
|
||||
|
||||
int load = 0;
|
||||
|
||||
if(containerType == ContainerType.FEU)
|
||||
{
|
||||
load = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FEU_LOAD).orElseThrow().getCurrentValue());
|
||||
} else if(containerType == ContainerType.TRUCK) {
|
||||
load = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.TRUCK_LOAD).orElseThrow().getCurrentValue());
|
||||
} else if(containerType == ContainerType.TEU) {
|
||||
load = Integer.parseInt(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.TEU_LOAD).orElseThrow().getCurrentValue());
|
||||
SystemPropertyMappingId mappingId = mappings.get(containerType);
|
||||
if (mappingId == null) {
|
||||
throw new IllegalArgumentException("Unsupported container type: " + containerType);
|
||||
}
|
||||
|
||||
return load;
|
||||
return Integer.parseInt(propertyRepository.getPropertyByMappingId(mappingId)
|
||||
.orElseThrow(() -> new IllegalStateException("Missing property: " + mappingId))
|
||||
.getCurrentValue());
|
||||
}
|
||||
|
||||
private int getLayerCount(PackagingDimension dimensions, ContainerType containerType) {
|
||||
return containerType.getHeight()/dimensions.getHeight();
|
||||
}
|
||||
|
||||
private ContainerCalculationResult toContainerCalculationResult(Solution solution, int layers, int maxUnitByWeight, ContainerType containerType, PackagingDimension hu, int maxContainerLoad) {
|
||||
ContainerCalculationResult result = new ContainerCalculationResult();
|
||||
private ContainerCalculationResult createContainerCalculationResult(
|
||||
Solution solution, int layers, int maxUnitByWeight,
|
||||
ContainerType containerType, PackagingDimension hu, int maxContainerLoad) {
|
||||
|
||||
result.setLayer(layers);
|
||||
result.setHuUnitCount(Math.min(solution.getTotal()*layers, maxUnitByWeight));
|
||||
result.setWeightExceeded(solution.getTotal() > maxUnitByWeight);
|
||||
result.setStructure(null);
|
||||
result.setContainerType(containerType);
|
||||
result.setHu(hu);
|
||||
result.setMaxContainerWeight(maxContainerLoad);
|
||||
int totalUnits = Math.min(solution.getTotal() * layers, maxUnitByWeight);
|
||||
boolean weightExceeded = solution.getTotal() > maxUnitByWeight;
|
||||
|
||||
return result;
|
||||
return new ContainerCalculationResult(
|
||||
totalUnits, layers, null, weightExceeded,
|
||||
containerType, hu, maxContainerLoad);
|
||||
}
|
||||
|
||||
private enum BlockType {
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.CustomResult;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobRouteSection;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.properties.CountryPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.CustomUnionType;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
|
||||
import de.avatic.lcc.repositories.premise.RouteNodeRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.service.CustomApiService;
|
||||
import de.avatic.lcc.calculationmodel.SectionInfo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class CustomCostCalculationService {
|
||||
|
||||
private final CustomApiService customApiService;
|
||||
private final CountryPropertyRepository countryPropertyRepository;
|
||||
private final RouteNodeRepository routeNodeRepository;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final ShippingFrequencyCalculationService shippingFrequencyCalculationService;
|
||||
|
||||
public CustomCostCalculationService(CustomApiService customApiService, CountryPropertyRepository countryPropertyRepository, RouteNodeRepository routeNodeRepository, PropertyRepository propertyRepository, ShippingFrequencyCalculationService shippingFrequencyCalculationService) {
|
||||
this.customApiService = customApiService;
|
||||
this.countryPropertyRepository = countryPropertyRepository;
|
||||
this.routeNodeRepository = routeNodeRepository;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.shippingFrequencyCalculationService = shippingFrequencyCalculationService;
|
||||
}
|
||||
|
||||
public CustomResult doD2dCalculation(Premise premise, Destination destination, CalculationJobRouteSection routeCost) {
|
||||
|
||||
var destUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, destination.getCountryId()).orElseThrow();
|
||||
var sourceUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, premise.getCountryId()).orElseThrow();
|
||||
|
||||
if (!CustomUnionType.EU.name().equals(destUnion.getCurrentValue()) || !CustomUnionType.NONE.name().equals(sourceUnion.getCurrentValue()))
|
||||
return CustomResult.EMPTY;
|
||||
|
||||
return getCustomCalculationResult(premise, destination, routeCost.getAnnualCost(), routeCost.getAnnualChanceCost(), routeCost.getAnnualRiskCost());
|
||||
}
|
||||
|
||||
public CustomResult doCalculation(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();
|
||||
|
||||
if (CustomUnionType.EU.name().equals(destUnion.getCurrentValue()) && CustomUnionType.NONE.name().equals(sourceUnion.getCurrentValue())) {
|
||||
var transportationCost = getCustomRelevantRouteSections(sections).stream().map(s -> s.result().getAnnualCost()).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
var transportationChanceCost = getCustomRelevantRouteSections(sections).stream().map(s -> s.result().getAnnualChanceCost()).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
var transportationRiskCost = getCustomRelevantRouteSections(sections).stream().map(s -> s.result().getAnnualChanceCost()).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
return getCustomCalculationResult(premise, destination, transportationCost, transportationChanceCost, transportationRiskCost);
|
||||
}
|
||||
|
||||
return CustomResult.EMPTY;
|
||||
}
|
||||
|
||||
private CustomResult getCustomCalculationResult(Premise premise, Destination destination, BigDecimal transportationCost, BigDecimal transportationChanceCost, BigDecimal transportationRiskCost) {
|
||||
var shippingFrequency = shippingFrequencyCalculationService.doCalculation(destination.getAnnualAmount());
|
||||
var customFee = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CUSTOM_FEE).orElseThrow().getCurrentValue());
|
||||
var tariffRate = customApiService.getTariffRate(premise.getHsCode(), premise.getCountryId());
|
||||
|
||||
var materialCost = premise.getMaterialCost();
|
||||
var fcaFee = BigDecimal.ZERO;
|
||||
|
||||
if (premise.getFcaEnabled()) {
|
||||
var fcaProperty = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FCA_FEE).orElseThrow();
|
||||
var fcaShare = Double.parseDouble(fcaProperty.getCurrentValue());
|
||||
fcaFee = BigDecimal.valueOf(fcaShare).multiply(materialCost);
|
||||
}
|
||||
|
||||
var customValue = materialCost.add(fcaFee).add(transportationCost);
|
||||
var customDuties = customValue.multiply(BigDecimal.valueOf(tariffRate));
|
||||
var annualCustomFee = shippingFrequency * customFee;
|
||||
var annualCost = customDuties.add(BigDecimal.valueOf(annualCustomFee));
|
||||
|
||||
var customRiskValue = materialCost.add(fcaFee).add(transportationRiskCost);
|
||||
var customRiskDuties = customRiskValue.multiply(BigDecimal.valueOf(tariffRate));
|
||||
var annualRiskCost = customRiskDuties.add(BigDecimal.valueOf(annualCustomFee));
|
||||
|
||||
var customChanceValue = materialCost.add(fcaFee).add(transportationChanceCost);
|
||||
var customChanceDuties = customChanceValue.multiply(BigDecimal.valueOf(tariffRate));
|
||||
var annualChanceCost = customChanceDuties.add(BigDecimal.valueOf(annualCustomFee));
|
||||
|
||||
return new CustomResult(customValue, customRiskValue, customChanceValue, customDuties, BigDecimal.valueOf(tariffRate), annualCost, annualRiskCost, annualChanceCost);
|
||||
}
|
||||
|
||||
private List<SectionInfo> getCustomRelevantRouteSections(List<SectionInfo> sections) {
|
||||
|
||||
List<SectionInfo> customSections = new ArrayList<>();
|
||||
|
||||
for (SectionInfo section : sections) {
|
||||
if (CustomUnionType.EU == getCustomUnionByRouteNodeId(section.section().getFromRouteNodeId()) &&
|
||||
CustomUnionType.EU == getCustomUnionByRouteNodeId(section.section().getToRouteNodeId())) {
|
||||
customSections.add(section);
|
||||
}
|
||||
}
|
||||
|
||||
return customSections;
|
||||
}
|
||||
|
||||
private CustomUnionType getCustomUnionByRouteNodeId(Integer routeNodeId) {
|
||||
var node = routeNodeRepository.getById(routeNodeId).orElseThrow();
|
||||
return getCustomUnionByCountryId(node.getCountryId());
|
||||
}
|
||||
|
||||
private CustomUnionType getCustomUnionByCountryId(Integer countryId) {
|
||||
var property = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, countryId).orElseThrow();
|
||||
return CustomUnionType.valueOf(property.getCurrentValue().toUpperCase());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.HandlingResult;
|
||||
import de.avatic.lcc.model.packaging.LoadCarrierType;
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.properties.CountryPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
public class HandlingCostCalculationService {
|
||||
|
||||
|
||||
private final CountryPropertyRepository countryPropertyRepository;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final PremiseToHuService premiseToHuService;
|
||||
|
||||
public HandlingCostCalculationService(CountryPropertyRepository countryPropertyRepository, PropertyRepository propertyRepository, PremiseToHuService premiseToHuService) {
|
||||
this.countryPropertyRepository = countryPropertyRepository;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.premiseToHuService = premiseToHuService;
|
||||
}
|
||||
|
||||
public HandlingResult doCalculation(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));
|
||||
}
|
||||
|
||||
private HandlingResult getSLCCost(Destination destination, PackagingDimension hu, LoadCarrierType loadCarrierType, boolean addRepackingCosts) {
|
||||
int huAnnualAmount = destination.getAnnualAmount() / hu.getContentUnitCount();
|
||||
double handling = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_HANDLING).orElseThrow().getCurrentValue());
|
||||
double release = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_RELEASE).orElseThrow().getCurrentValue());
|
||||
double dispatch = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_DISPATCH).orElseThrow().getCurrentValue());
|
||||
double wageFactor = Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.WAGE, destination.getCountryId()).orElseThrow().getCurrentValue());
|
||||
double booking = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING).orElseThrow().getCurrentValue());
|
||||
|
||||
return new HandlingResult(LoadCarrierType.SLC,
|
||||
BigDecimal.valueOf(getRepackingCost(hu, loadCarrierType, addRepackingCosts) * huAnnualAmount),
|
||||
BigDecimal.valueOf(handling*huAnnualAmount),
|
||||
BigDecimal.ZERO,
|
||||
BigDecimal.valueOf(huAnnualAmount * (handling + booking + release + dispatch + getRepackingCost(hu, loadCarrierType, addRepackingCosts)) * wageFactor));
|
||||
|
||||
}
|
||||
|
||||
private double getRepackingCost(PackagingDimension hu, LoadCarrierType type, boolean addRepackingCosts) {
|
||||
|
||||
if (!addRepackingCosts)
|
||||
return 0;
|
||||
|
||||
return switch (type) {
|
||||
case SLC ->
|
||||
Double.parseDouble((hu.getWeight() < 15.000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_REPACK_S).orElseThrow().getCurrentValue() : propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.KLT_REPACK_M).orElseThrow().getCurrentValue());
|
||||
case LLC ->
|
||||
Double.parseDouble(((hu.getWeight() < 15.000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_S) : (hu.getWeight() < 2000.000) ? propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_M) : propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_REPACK_L)).orElseThrow().getCurrentValue());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private HandlingResult getLLCCost(Destination destination, PackagingDimension hu, LoadCarrierType type, boolean addRepackingCosts) {
|
||||
int huAnnualAmount = destination.getAnnualAmount() / hu.getContentUnitCount();
|
||||
double handling = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_HANDLING).orElseThrow().getCurrentValue());
|
||||
double release = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_RELEASE).orElseThrow().getCurrentValue());
|
||||
double dispatch = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.GLT_DISPATCH).orElseThrow().getCurrentValue());
|
||||
double disposal = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.DISPOSAL).orElseThrow().getCurrentValue());
|
||||
|
||||
double wageFactor = Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.WAGE, destination.getCountryId()).orElseThrow().getCurrentValue());
|
||||
double booking = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING).orElseThrow().getCurrentValue());
|
||||
|
||||
return new HandlingResult(LoadCarrierType.SLC,
|
||||
BigDecimal.valueOf(getRepackingCost(hu, type, addRepackingCosts) * huAnnualAmount),
|
||||
BigDecimal.valueOf(handling*huAnnualAmount),
|
||||
BigDecimal.valueOf(disposal * huAnnualAmount),
|
||||
BigDecimal.valueOf(huAnnualAmount * (((handling + booking + release + dispatch + getRepackingCost(hu, type, addRepackingCosts)) * wageFactor) + disposal)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.InventoryCostResult;
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.properties.CountryPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.utils.DimensionUnit;
|
||||
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
@Service
|
||||
public class InventoryCostCalculationService {
|
||||
|
||||
|
||||
private final ShippingFrequencyCalculationService shippingFrequencyCalculationService;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final CountryPropertyRepository countryPropertyRepository;
|
||||
private final PremiseToHuService premiseToHuService;
|
||||
|
||||
public InventoryCostCalculationService(ShippingFrequencyCalculationService shippingFrequencyCalculationService, PropertyRepository propertyRepository, CountryPropertyRepository countryPropertyRepository, PremiseToHuService premiseToHuService) {
|
||||
this.shippingFrequencyCalculationService = shippingFrequencyCalculationService;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.countryPropertyRepository = countryPropertyRepository;
|
||||
this.premiseToHuService = premiseToHuService;
|
||||
}
|
||||
|
||||
public InventoryCostResult doCalculation(Premise premise, Destination destination, BigDecimal leadTime) {
|
||||
|
||||
var fcaFee = BigDecimal.ZERO;
|
||||
|
||||
if (premise.getFcaEnabled()) {
|
||||
var fcaProperty = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.FCA_FEE).orElseThrow();
|
||||
var fcaShare = Double.parseDouble(fcaProperty.getCurrentValue());
|
||||
fcaFee = BigDecimal.valueOf(fcaShare).multiply(premise.getMaterialCost());
|
||||
}
|
||||
|
||||
var hu = premiseToHuService.createHuFromPremise(premise);
|
||||
|
||||
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 annualAmount = BigDecimal.valueOf(destination.getAnnualAmount().doubleValue());
|
||||
var dailyAmount = annualAmount.divide(BigDecimal.valueOf(365));
|
||||
var workdayAmount = annualAmount.divide(workdays);
|
||||
|
||||
var opStock = (annualAmount.divide(BigDecimal.valueOf(Math.max(shippingFrequencyCalculationService.doCalculation(destination.getAnnualAmount()),1))).multiply(BigDecimal.valueOf(.5)));
|
||||
var safetyStock = safetydays.multiply(workdayAmount);
|
||||
var stockedInventory = opStock.add(safetyStock);
|
||||
var inTransportStock = dailyAmount.multiply(leadTime);
|
||||
var stockBeforePayment = dailyAmount.multiply(paymentTerms);
|
||||
|
||||
var capitalCostStock = stockedInventory.add(inTransportStock).subtract(stockBeforePayment);
|
||||
var storageCostStock = roundToHu(hu, safetyStock).add(opStock);
|
||||
|
||||
var capitalCost = capitalCostStock.multiply(interestRate).multiply(premise.getMaterialCost().add(fcaFee));
|
||||
var storageCost = storageCostStock.divide(BigDecimal.valueOf(hu.getContentUnitCount())).multiply(getSpaceCostPerHu(hu));
|
||||
|
||||
|
||||
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()));
|
||||
return BigDecimal.valueOf(hu.getFloorArea(DimensionUnit.M)*hu.getRoundedHeight(DimensionUnit.M)).multiply(spaceCost);
|
||||
}
|
||||
|
||||
private BigDecimal roundToHu(PackagingDimension hu, BigDecimal safetyStock) {
|
||||
return safetyStock.divide(BigDecimal.valueOf(hu.getContentUnitCount()), 0, RoundingMode.UP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.packaging.PackagingType;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PremiseToHuService {
|
||||
|
||||
public PackagingDimension createHuFromPremise(Premise premise) {
|
||||
var hu = new PackagingDimension();
|
||||
|
||||
hu.setWeight(premise.getIndividualHuWeight());
|
||||
hu.setWeightUnit(premise.getHuDisplayedWeightUnit());
|
||||
|
||||
hu.setHeight(premise.getIndividualHuHeight());
|
||||
hu.setWidth(premise.getIndividualHuWidth());
|
||||
hu.setLength(premise.getIndividualHuLength());
|
||||
hu.setDimensionUnit(premise.getHuDisplayedDimensionUnit());
|
||||
|
||||
hu.setContentUnitCount(premise.getHuUnitCount());
|
||||
hu.setType(PackagingType.HU);
|
||||
|
||||
return hu;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,255 @@
|
|||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.calculationmodel.ContainerCalculationResult;
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
import de.avatic.lcc.dto.generic.RateType;
|
||||
import de.avatic.lcc.dto.generic.TransportType;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobRouteSection;
|
||||
import de.avatic.lcc.model.nodes.Location;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.premises.route.RouteNode;
|
||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.rates.ContainerRate;
|
||||
import de.avatic.lcc.model.rates.MatrixRate;
|
||||
import de.avatic.lcc.model.utils.DimensionUnit;
|
||||
import de.avatic.lcc.repositories.premise.RouteNodeRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.repositories.rates.ContainerRateRepository;
|
||||
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
||||
import de.avatic.lcc.service.calculation.DistanceService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
@Service
|
||||
public class RouteSectionCostCalculationService {
|
||||
|
||||
private final ContainerRateRepository containerRateRepository;
|
||||
private final MatrixRateRepository matrixRateRepository;
|
||||
private final RouteNodeRepository routeNodeRepository;
|
||||
private final DistanceService distanceService;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final ChangeRiskFactorCalculationService changeRiskFactorCalculationService;
|
||||
|
||||
public RouteSectionCostCalculationService(ContainerRateRepository containerRateRepository, MatrixRateRepository matrixRateRepository, RouteNodeRepository routeNodeRepository, DistanceService distanceService, PropertyRepository propertyRepository, ChangeRiskFactorCalculationService changeRiskFactorCalculationService) {
|
||||
this.containerRateRepository = containerRateRepository;
|
||||
this.matrixRateRepository = matrixRateRepository;
|
||||
this.routeNodeRepository = routeNodeRepository;
|
||||
this.distanceService = distanceService;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.changeRiskFactorCalculationService = changeRiskFactorCalculationService;
|
||||
}
|
||||
|
||||
public CalculationJobRouteSection doD2dCalculation(Premise premise, Destination destination, ContainerCalculationResult containerCalculation) {
|
||||
CalculationJobRouteSection result = new CalculationJobRouteSection();
|
||||
|
||||
// Set route metadata
|
||||
result.setMainRun(false);
|
||||
result.setPostRun(false);
|
||||
result.setPreRun(false);
|
||||
result.setTransportType(null);
|
||||
result.setRateType(RateType.D2D);
|
||||
|
||||
// Set premise metadata
|
||||
result.setStacked(premise.getHuStackable());
|
||||
result.setUnmixedPrice(premise.getHuMixable());
|
||||
|
||||
// Get nodes and distance
|
||||
RouteNode fromNode = routeNodeRepository.getById(premise.getSupplierNodeId()).orElseThrow();
|
||||
RouteNode toNode = routeNodeRepository.getById(destination.getDestinationNodeId()).orElseThrow();
|
||||
double distance = getDistance(fromNode, toNode);
|
||||
result.setDistance(BigDecimal.valueOf(distance));
|
||||
|
||||
// Get rate and transit time
|
||||
BigDecimal rate = destination.getRateD2d();
|
||||
int transitTime = destination.getLeadTimeD2d();
|
||||
|
||||
result.setRate(rate);
|
||||
result.setTransitTime(transitTime);
|
||||
|
||||
// Calculate price and annual cost
|
||||
BigDecimal utilization = getUtilization(RateType.CONTAINER); /* D2D is always 40ft container */
|
||||
double annualVolume = destination.getAnnualAmount() * containerCalculation.getHu().getVolume(DimensionUnit.M);
|
||||
|
||||
PriceCalculationResult prices = calculatePrices(
|
||||
premise.getHuMixable(),
|
||||
rate,
|
||||
ContainerType.FEU,
|
||||
containerCalculation.getMaxContainerWeight(),
|
||||
BigDecimal.valueOf(containerCalculation.getTotalUtilizationByVolume()),
|
||||
utilization);
|
||||
|
||||
result.setCbmPrice(!containerCalculation.isWeightExceeded());
|
||||
result.setWeightPrice(containerCalculation.isWeightExceeded());
|
||||
result.setCbmPrice(prices.volumePrice);
|
||||
result.setWeightPrice(prices.weightPrice);
|
||||
|
||||
var chanceRiskFactors = changeRiskFactorCalculationService.getChanceRiskFactors();
|
||||
|
||||
BigDecimal annualCost = (containerCalculation.isWeightExceeded() ? prices.weightPrice : prices.volumePrice).multiply(BigDecimal.valueOf(annualVolume));
|
||||
BigDecimal annualRiskCost = annualCost.multiply(chanceRiskFactors.getRiskFactor());
|
||||
BigDecimal annualChanceCost = annualCost.multiply(chanceRiskFactors.getChanceFactor());
|
||||
|
||||
result.setAnnualRiskCost(annualRiskCost);
|
||||
result.setAnnualChanceCost(annualChanceCost);
|
||||
result.setAnnualCost(annualCost);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public CalculationJobRouteSection doCalculation(Premise premise, Destination destination, RouteSection section, ContainerCalculationResult containerCalculation) {
|
||||
CalculationJobRouteSection result = new CalculationJobRouteSection();
|
||||
|
||||
// Set route metadata
|
||||
result.setMainRun(section.getMainRun());
|
||||
result.setPostRun(section.getPostRun());
|
||||
result.setPreRun(section.getPreRun());
|
||||
result.setTransportType(TransportType.valueOf(section.getTransportType().name()));
|
||||
result.setRateType(RateType.valueOf(section.getRateType().name()));
|
||||
|
||||
// Set premise metadata
|
||||
result.setStacked(premise.getHuStackable());
|
||||
result.setUnmixedPrice(premise.getHuMixable());
|
||||
|
||||
// Get nodes and distance
|
||||
RouteNode fromNode = routeNodeRepository.getById(section.getFromRouteNodeId()).orElseThrow();
|
||||
RouteNode toNode = routeNodeRepository.getById(section.getToRouteNodeId()).orElseThrow();
|
||||
double distance = getDistance(fromNode, toNode);
|
||||
result.setDistance(BigDecimal.valueOf(distance));
|
||||
|
||||
// Get rate and transit time
|
||||
BigDecimal rate;
|
||||
int transitTime;
|
||||
|
||||
if (RateType.CONTAINER == section.getRateType()) {
|
||||
ContainerRate containerRate = findContainerRate(section);
|
||||
rate = getContainerRate(containerRate, containerCalculation.getContainerType());
|
||||
transitTime = containerRate.getLeadTime();
|
||||
} else if (RateType.MATRIX == section.getRateType()) {
|
||||
MatrixRate matrixRate = findMatrixRate(fromNode, toNode);
|
||||
rate = matrixRate.getRate().multiply(BigDecimal.valueOf(distance));
|
||||
transitTime = 3; // Default transit time for matrix rate
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported rate type: " + section.getRateType());
|
||||
}
|
||||
|
||||
result.setRate(rate);
|
||||
result.setTransitTime(transitTime);
|
||||
|
||||
// Calculate price and annual cost
|
||||
BigDecimal utilization = getUtilization(section.getRateType());
|
||||
double annualVolume = destination.getAnnualAmount() * containerCalculation.getHu().getVolume(DimensionUnit.M);
|
||||
|
||||
PriceCalculationResult prices = calculatePrices(
|
||||
premise.getHuMixable(),
|
||||
rate,
|
||||
containerCalculation.getContainerType(),
|
||||
containerCalculation.getMaxContainerWeight(),
|
||||
BigDecimal.valueOf(containerCalculation.getTotalUtilizationByVolume()),
|
||||
utilization);
|
||||
|
||||
result.setCbmPrice(!containerCalculation.isWeightExceeded());
|
||||
result.setWeightPrice(containerCalculation.isWeightExceeded());
|
||||
result.setCbmPrice(prices.volumePrice);
|
||||
result.setWeightPrice(prices.weightPrice);
|
||||
|
||||
var chanceRiskFactors = changeRiskFactorCalculationService.getChanceRiskFactors();
|
||||
|
||||
BigDecimal annualCost = (containerCalculation.isWeightExceeded() ? prices.weightPrice : prices.volumePrice).multiply(BigDecimal.valueOf(annualVolume));
|
||||
BigDecimal annualRiskCost = annualCost.multiply(chanceRiskFactors.getRiskFactor());
|
||||
BigDecimal annualChanceCost = annualCost.multiply(chanceRiskFactors.getChanceFactor());
|
||||
|
||||
result.setAnnualRiskCost(annualRiskCost);
|
||||
result.setAnnualChanceCost(annualChanceCost);
|
||||
result.setAnnualCost(annualCost);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private PriceCalculationResult calculatePrices(
|
||||
boolean huMixable,
|
||||
BigDecimal rate,
|
||||
ContainerType containerType,
|
||||
int maxContainerWeight,
|
||||
BigDecimal totalVolumeUtilization,
|
||||
BigDecimal utilization) {
|
||||
|
||||
BigDecimal volumePrice;
|
||||
BigDecimal weightPrice;
|
||||
|
||||
BigDecimal cbmRate = rate.divide(BigDecimal.valueOf(containerType.getVolume()));
|
||||
if (huMixable) {
|
||||
volumePrice = cbmRate.divide(utilization);
|
||||
weightPrice = (rate.divide(BigDecimal.valueOf(maxContainerWeight))).divide(utilization);
|
||||
} else {
|
||||
volumePrice = cbmRate.divide(totalVolumeUtilization);
|
||||
weightPrice = (rate.divide(BigDecimal.valueOf(maxContainerWeight))).divide(totalVolumeUtilization);
|
||||
}
|
||||
|
||||
return new PriceCalculationResult(volumePrice, weightPrice);
|
||||
}
|
||||
|
||||
private ContainerRate findContainerRate(RouteSection section) {
|
||||
return containerRateRepository.findRoute(
|
||||
section.getFromRouteNodeId(),
|
||||
section.getToRouteNodeId(),
|
||||
TransportType.valueOf(section.getTransportType().name()))
|
||||
.orElseThrow(() -> new NoSuchElementException(
|
||||
"ContainerRate not found for route: " + section.getFromRouteNodeId() +
|
||||
" to " + section.getToRouteNodeId()));
|
||||
}
|
||||
|
||||
private MatrixRate findMatrixRate(RouteNode fromNode, RouteNode toNode) {
|
||||
return matrixRateRepository.getByCountryIds(fromNode.getCountryId(), toNode.getCountryId())
|
||||
.orElseThrow(() -> new NoSuchElementException(
|
||||
"MatrixRate not found for countries: " + fromNode.getCountryId() +
|
||||
" to " + toNode.getCountryId()));
|
||||
}
|
||||
|
||||
private BigDecimal getUtilization(RateType rateType) {
|
||||
BigDecimal utilization;
|
||||
if (rateType == RateType.CONTAINER) {
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CONTAINER_UTIL).orElseThrow().getCurrentValue()));
|
||||
}
|
||||
else if (rateType == RateType.MATRIX) {
|
||||
utilization = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.TRUCK_UTIL).orElseThrow().getCurrentValue()));
|
||||
} else
|
||||
throw new IllegalArgumentException("Unknown rate type");
|
||||
|
||||
return utilization;
|
||||
}
|
||||
|
||||
|
||||
private BigDecimal getContainerRate(ContainerRate rate, ContainerType containerType) {
|
||||
|
||||
switch (containerType) {
|
||||
case HQ -> {
|
||||
return rate.getRateHc();
|
||||
}
|
||||
case FEU -> {
|
||||
return rate.getRateFeu();
|
||||
}
|
||||
case TEU -> {
|
||||
return rate.getRateTeu();
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown container type");
|
||||
}
|
||||
|
||||
private double getDistance(RouteNode fromNode, RouteNode toNode) {
|
||||
return distanceService.getDistanceFast(
|
||||
fromNode.getCountryId(), new Location(fromNode.getGeoLng().doubleValue(), fromNode.getGeoLat().doubleValue()),
|
||||
toNode.getCountryId(), new Location(toNode.getGeoLng().doubleValue(), toNode.getGeoLat().doubleValue()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple data class to hold volume and weight price results
|
||||
*/
|
||||
private record PriceCalculationResult(BigDecimal volumePrice, BigDecimal weightPrice) {}
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
package de.avatic.lcc.service.calculation.execution.steps;
|
||||
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.utils.DimensionUnit;
|
||||
import de.avatic.lcc.model.utils.WeightUnit;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AirfreightCalculationService {
|
||||
|
||||
private final PropertyRepository propertyRepository;
|
||||
|
||||
public AirfreightCalculationService(PropertyRepository propertyRepository) {
|
||||
this.propertyRepository = propertyRepository;
|
||||
}
|
||||
|
||||
public double doCalculation(PackagingDimension hu, double annualHuAmount) {
|
||||
|
||||
var preCarriage = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_PRECARRIAGE).orElseThrow().getCurrentValue());
|
||||
var mainCarriage = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_MAINCARRIAGE).orElseThrow().getCurrentValue());
|
||||
var postCarriage = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_ONCARRIAGE).orElseThrow().getCurrentValue());
|
||||
var terminalFee = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_TERMINAL_FEE).orElseThrow().getCurrentValue());
|
||||
var preCarriageFee = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_HANDLING).orElseThrow().getCurrentValue());
|
||||
var customsClearanceFee = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_CUSTOM_FEE).orElseThrow().getCurrentValue());
|
||||
var handOverFee = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.AIR_HANDOVER_FEE).orElseThrow().getCurrentValue());
|
||||
|
||||
return 1.08*((getShippingWeight(hu)* preCarriage+mainCarriage+postCarriage+terminalFee)+preCarriageFee+customsClearanceFee+handOverFee);
|
||||
|
||||
}
|
||||
|
||||
private double getShippingWeight(PackagingDimension hu) {
|
||||
return Math.max(getWeightInKg(hu), getVolumeWeight(hu));
|
||||
}
|
||||
|
||||
private double getVolumeWeight(PackagingDimension hu) {
|
||||
return 0.0002 * getDimensionInCm(hu.getLength(), hu.getDimensionUnit()) * getDimensionInCm(hu.getWidth(), hu.getDimensionUnit()) * getDimensionInCm(hu.getHeight(), hu.getDimensionUnit()) ;
|
||||
}
|
||||
|
||||
private double getDimensionInCm(Number dimension, DimensionUnit unit) {
|
||||
return DimensionUnit.CM.convertFromMM(dimension).doubleValue();
|
||||
}
|
||||
|
||||
private double getWeightInKg(PackagingDimension hu) {
|
||||
return WeightUnit.KG.convertFromG(hu.getWeight()).doubleValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
|
||||
import de.avatic.lcc.model.properties.CountryPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AirfreightShareCalculationService {
|
||||
|
||||
private final CountryPropertyRepository propertyRepository;
|
||||
|
||||
public AirfreightShareCalculationService(CountryPropertyRepository propertyRepository) {
|
||||
this.propertyRepository = propertyRepository;
|
||||
}
|
||||
|
||||
public double doCalculation(double overseaShare, Integer countryId) {
|
||||
var maxAirfreightShare = Double.parseDouble(propertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.AIR_SHARE, countryId).orElseThrow().getCurrentValue());
|
||||
|
||||
// Ensure oversea share is within valid range
|
||||
if (overseaShare < 0 || overseaShare > 100) {
|
||||
throw new IllegalArgumentException("Oversea share must be between 0 and 100");
|
||||
}
|
||||
|
||||
// First segment: from (0,0) to (50, 20% of max)
|
||||
if (overseaShare <= 50) {
|
||||
// Linear interpolation: y = mx + b
|
||||
// m = (0.2 * maxAirfreightShare - 0) / (50 - 0) = 0.004 * maxAirfreightShare
|
||||
// b = 0
|
||||
return 0.004 * maxAirfreightShare * overseaShare;
|
||||
}
|
||||
// Second segment: from (50, 20% of max) to (100, max)
|
||||
else {
|
||||
// Linear interpolation: y = mx + b
|
||||
// m = (maxAirfreightShare - 0.2 * maxAirfreightShare) / (100 - 50) = 0.016 * maxAirfreightShare
|
||||
// b = 0.2 * maxAirfreightShare - 50 * 0.016 * maxAirfreightShare = -0.6 * maxAirfreightShare
|
||||
return 0.016 * maxAirfreightShare * overseaShare - 0.6 * maxAirfreightShare;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
|
||||
import de.avatic.lcc.model.country.Country;
|
||||
import de.avatic.lcc.model.premises.route.Route;
|
||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||
import de.avatic.lcc.model.properties.CountryPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.CustomUnionType;
|
||||
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
|
||||
import de.avatic.lcc.repositories.premise.RouteNodeRepository;
|
||||
import de.avatic.lcc.service.CustomApiService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class CustomCostCalculationService {
|
||||
|
||||
private final CustomApiService customApiService;
|
||||
private final CountryPropertyRepository countryPropertyRepository;
|
||||
private final RouteNodeRepository routeNodeRepository;
|
||||
|
||||
public CustomCostCalculationService(CustomApiService customApiService, CountryPropertyRepository countryPropertyRepository, RouteNodeRepository routeNodeRepository) {
|
||||
this.customApiService = customApiService;
|
||||
this.countryPropertyRepository = countryPropertyRepository;
|
||||
this.routeNodeRepository = routeNodeRepository;
|
||||
}
|
||||
|
||||
public double doCalculation(String hsCode, Country supplierCountry, Country destinationCountry, Route route, List<RouteSection> section) {
|
||||
|
||||
var destUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, destinationCountry.getId()).orElseThrow();
|
||||
var sourceUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, supplierCountry.getId()).orElseThrow();
|
||||
|
||||
if (CustomUnionType.EU.name().equals(destUnion.getCurrentValue()) && CustomUnionType.NONE.name().equals(sourceUnion.getCurrentValue())) {
|
||||
var tariffRate = customApiService.getTariffRate(hsCode, supplierCountry.getId());
|
||||
|
||||
getCustomRelevantRouteSections(section);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
private List<RouteSection> getCustomRelevantRouteSections(List<RouteSection> sections) {
|
||||
|
||||
List<RouteSection> customSections = new ArrayList<>();
|
||||
|
||||
for(RouteSection section : sections) {
|
||||
if(CustomUnionType.EU == getCustomUnionByRouteNodeId(section.getFromRouteNodeId()) &&
|
||||
CustomUnionType.EU ==getCustomUnionByRouteNodeId(section.getToRouteNodeId())) {
|
||||
customSections.add(section);
|
||||
}
|
||||
}
|
||||
|
||||
return customSections;
|
||||
}
|
||||
|
||||
private CustomUnionType getCustomUnionByRouteNodeId(Integer routeNodeId) {
|
||||
var node = routeNodeRepository.getById(routeNodeId).orElseThrow();
|
||||
return getCustomUnionByCountryId(node.getCountryId());
|
||||
}
|
||||
|
||||
private CustomUnionType getCustomUnionByCountryId(Integer countryId) {
|
||||
var property = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, countryId).orElseThrow();
|
||||
return CustomUnionType.valueOf(property.getCurrentValue().toUpperCase());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class Door2DoorCostCalculationService {
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class HandlingCostCalculationService {
|
||||
|
||||
|
||||
public void doCalculation() {
|
||||
|
||||
}
|
||||
|
||||
private void calculateHandlingCost() {
|
||||
}
|
||||
|
||||
private void calculateInventoryCost() {
|
||||
|
||||
}
|
||||
private void calculateCapitalCost() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
package de.avatic.lcc.service.calculation.steps;
|
||||
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
import de.avatic.lcc.dto.generic.RateType;
|
||||
import de.avatic.lcc.dto.generic.TransportType;
|
||||
import de.avatic.lcc.model.calculations.CalculationJobRouteSection;
|
||||
import de.avatic.lcc.model.nodes.Location;
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.packaging.PackagingType;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.premises.route.RouteNode;
|
||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.rates.ContainerRate;
|
||||
import de.avatic.lcc.model.rates.MatrixRate;
|
||||
import de.avatic.lcc.model.utils.DimensionUnit;
|
||||
import de.avatic.lcc.repositories.premise.RouteNodeRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.repositories.rates.ContainerRateRepository;
|
||||
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
||||
import de.avatic.lcc.service.calculation.DistanceService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Service
|
||||
public class RouteSectionCostCalculationService {
|
||||
|
||||
|
||||
private final ContainerCalculationService containerCalculationService;
|
||||
private final ContainerRateRepository containerRateRepository;
|
||||
private final MatrixRateRepository matrixRateRepository;
|
||||
private final RouteNodeRepository routeNodeRepository;
|
||||
private final DistanceService distanceService;
|
||||
private final PropertyRepository propertyRepository;
|
||||
|
||||
public RouteSectionCostCalculationService(ContainerCalculationService containerCalculationService, ContainerRateRepository containerRateRepository, MatrixRateRepository matrixRateRepository, RouteNodeRepository routeNodeRepository, DistanceService distanceService, PropertyRepository propertyRepository) {
|
||||
this.containerCalculationService = containerCalculationService;
|
||||
this.containerRateRepository = containerRateRepository;
|
||||
this.matrixRateRepository = matrixRateRepository;
|
||||
this.routeNodeRepository = routeNodeRepository;
|
||||
this.distanceService = distanceService;
|
||||
this.propertyRepository = propertyRepository;
|
||||
}
|
||||
|
||||
public CalculationJobRouteSection doCalculation(Premise premise, Destination destination, RouteSection section, ContainerType containerType) {
|
||||
CalculationJobRouteSection calculationJobRouteSection = new CalculationJobRouteSection();
|
||||
|
||||
double utilization = getUtilization(section);
|
||||
RouteNode fromNode = routeNodeRepository.getById(section.getFromRouteNodeId()).orElseThrow();
|
||||
RouteNode toNode = routeNodeRepository.getById(section.getFromRouteNodeId()).orElseThrow();
|
||||
double distance = getDistance(fromNode, toNode);
|
||||
|
||||
int annualAmount = destination.getAnnualAmount();
|
||||
var containerCalculationResult = containerCalculationService.doCalculation(createHu(premise), containerType);
|
||||
var annualVolume = annualAmount * containerCalculationResult.getHu().getVolume(DimensionUnit.M);
|
||||
var transitTime = 3;
|
||||
|
||||
ContainerRate containerRate = containerRateRepository.findRoute(section.getFromRouteNodeId(), section.getToRouteNodeId(), TransportType.valueOf(section.getTransportType().name())).orElseThrow();
|
||||
MatrixRate matrixRate = matrixRateRepository.getByCountryIds(fromNode.getCountryId(), toNode.getCountryId()).orElseThrow();
|
||||
|
||||
var rate = 0.0;
|
||||
if (RateType.CONTAINER == section.getRateType()) {
|
||||
rate = getContainerRate(containerRate, containerType);
|
||||
transitTime = containerRate.getLeadTime();
|
||||
} else if (RateType.MATRIX == section.getRateType()) {
|
||||
rate = getTruckRate(matrixRate, distance);
|
||||
}
|
||||
|
||||
double volumePrice;
|
||||
double weightPrice;
|
||||
|
||||
if (premise.getHuMixable()) {
|
||||
volumePrice = (rate / containerType.getVolume()) / utilization;
|
||||
weightPrice = (rate / containerCalculationResult.getMaxContainerWeight()) / utilization;
|
||||
|
||||
} else {
|
||||
volumePrice = (rate / containerType.getVolume()) / containerCalculationResult.getTotalUtilizationByVolume();
|
||||
weightPrice = (rate / containerCalculationResult.getMaxContainerWeight()) / containerCalculationResult.getTotalUtilizationByVolume();
|
||||
}
|
||||
|
||||
double annualCost = annualVolume * (containerCalculationResult.isWeightExceeded() ? weightPrice : volumePrice);
|
||||
|
||||
calculationJobRouteSection.setCbmPrice(!containerCalculationResult.isWeightExceeded());
|
||||
calculationJobRouteSection.setWeightPrice(containerCalculationResult.isWeightExceeded());
|
||||
calculationJobRouteSection.setCbmPrice(BigDecimal.valueOf(volumePrice));
|
||||
calculationJobRouteSection.setWeightPrice(BigDecimal.valueOf(weightPrice));
|
||||
|
||||
calculationJobRouteSection.setDistance(BigDecimal.valueOf(distance));
|
||||
calculationJobRouteSection.setRate(BigDecimal.valueOf(rate));
|
||||
|
||||
calculationJobRouteSection.setMainRun(section.getMainRun());
|
||||
calculationJobRouteSection.setPostRun(section.getPostRun());
|
||||
calculationJobRouteSection.setPreRun(section.getPreRun());
|
||||
|
||||
calculationJobRouteSection.setStacked(premise.getHuStackable());
|
||||
calculationJobRouteSection.setUnmixedPrice(premise.getHuMixable());
|
||||
|
||||
calculationJobRouteSection.setTransportType(TransportType.valueOf(section.getTransportType().name()));
|
||||
calculationJobRouteSection.setRateType(RateType.valueOf(section.getRateType().name()));
|
||||
|
||||
calculationJobRouteSection.setRate(BigDecimal.valueOf(rate));
|
||||
calculationJobRouteSection.setAnnualCost(BigDecimal.valueOf(annualCost));
|
||||
|
||||
calculationJobRouteSection.setTransitTime(transitTime);
|
||||
|
||||
return calculationJobRouteSection;
|
||||
}
|
||||
|
||||
private double getUtilization(RouteSection section) {
|
||||
double utilization = 0;
|
||||
if (section.getRateType() == RateType.CONTAINER) {
|
||||
utilization = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.CONTAINER_UTIL).orElseThrow().getCurrentValue());
|
||||
}
|
||||
else if (section.getRateType() == RateType.MATRIX) {
|
||||
utilization = Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.TRUCK_UTIL).orElseThrow().getCurrentValue());
|
||||
} else
|
||||
throw new IllegalArgumentException("Unknown rate type");
|
||||
|
||||
return utilization;
|
||||
}
|
||||
|
||||
private PackagingDimension createHu(Premise premise) {
|
||||
var hu = new PackagingDimension();
|
||||
|
||||
hu.setWeight(premise.getIndividualHuWeight());
|
||||
hu.setWeightUnit(premise.getHuDisplayedWeightUnit());
|
||||
|
||||
hu.setHeight(premise.getIndividualHuHeight());
|
||||
hu.setWidth(premise.getIndividualHuWidth());
|
||||
hu.setLength(premise.getIndividualHuLength());
|
||||
hu.setDimensionUnit(premise.getHuDisplayedDimensionUnit());
|
||||
|
||||
hu.setContentUnitCount(premise.getHuUnitCount());
|
||||
hu.setType(PackagingType.HU);
|
||||
|
||||
return hu;
|
||||
}
|
||||
|
||||
|
||||
private double getContainerRate(ContainerRate rate, ContainerType containerType) {
|
||||
|
||||
switch (containerType) {
|
||||
case HQ -> {
|
||||
return rate.getRateHc().doubleValue();
|
||||
}
|
||||
case FEU -> {
|
||||
return rate.getRateFeu().doubleValue();
|
||||
}
|
||||
case TEU -> {
|
||||
return rate.getRateTeu().doubleValue();
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown container type");
|
||||
}
|
||||
|
||||
private double getDistance(RouteNode fromNode, RouteNode toNode) {
|
||||
return distanceService.getDistanceFast(
|
||||
fromNode.getCountryId(), new Location(fromNode.getGeoLng().doubleValue(), fromNode.getGeoLat().doubleValue()),
|
||||
toNode.getCountryId(), new Location(fromNode.getGeoLng().doubleValue(), fromNode.getGeoLat().doubleValue()));
|
||||
}
|
||||
|
||||
private double getTruckRate(MatrixRate rate, double distance) {
|
||||
|
||||
return rate.getRate().doubleValue() * distance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package de.avatic.lcc.service.transformer.report;
|
||||
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
import de.avatic.lcc.dto.generic.NodeDTO;
|
||||
import de.avatic.lcc.dto.generic.NodeType;
|
||||
import de.avatic.lcc.dto.report.ReportDTO;
|
||||
import de.avatic.lcc.dto.report.ReportDestinationDTO;
|
||||
|
|
@ -14,10 +13,8 @@ import de.avatic.lcc.model.premises.Premise;
|
|||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.repositories.calculation.CalculationJobDestinationRepository;
|
||||
import de.avatic.lcc.repositories.calculation.CalculationJobRouteSectionRepository;
|
||||
import de.avatic.lcc.repositories.premise.DestinationRepository;
|
||||
import de.avatic.lcc.repositories.premise.PremiseRepository;
|
||||
import de.avatic.lcc.repositories.premise.RouteNodeRepository;
|
||||
import de.avatic.lcc.repositories.premise.RouteSectionRepository;
|
||||
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
|
@ -106,7 +103,7 @@ public class ReportTransformer {
|
|||
|
||||
destinationDTO.setMixed(premise.getHuMixable());
|
||||
destinationDTO.setRate(mainRun == null ? 0 : mainRun.getRate());
|
||||
destinationDTO.setType(ContainerType.valueOf(destination.getTransportationType()));
|
||||
destinationDTO.setType(ContainerType.valueOf(destination.getContainerType()));
|
||||
destinationDTO.setUtilization(destination.getContainerUtilization());
|
||||
destinationDTO.setUnitCount(premise.getHuUnitCount());
|
||||
destinationDTO.setWeightExceeded(destination.getTransportWeightExceeded());
|
||||
|
|
@ -148,13 +145,13 @@ public class ReportTransformer {
|
|||
risk.put("air_freight_cost", airfreight);
|
||||
|
||||
ReportEntryDTO worst = new ReportEntryDTO();
|
||||
var worstValue = destination.stream().map(CalculationJobDestination::getAnnualRiskCost).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
var worstValue = destination.stream().map(CalculationJobDestination::getTotalRiskCost).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
worst.setTotal(worstValue);
|
||||
worst.setPercentage(worstValue.divide(totalValue, 2, RoundingMode.HALF_UP));
|
||||
risk.put("worst_case_cost", worst);
|
||||
|
||||
ReportEntryDTO best = new ReportEntryDTO();
|
||||
var bestValue = destination.stream().map(CalculationJobDestination::getAnnualChanceCost).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
var bestValue = destination.stream().map(CalculationJobDestination::getTotalChanceCost).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
best.setTotal(bestValue);
|
||||
best.setPercentage(bestValue.divide(totalValue, 2, RoundingMode.HALF_UP));
|
||||
risk.put("best_case_cost", best);
|
||||
|
|
|
|||
645
src/main/resources/data-country.sql
Normal file
645
src/main/resources/data-country.sql
Normal file
|
|
@ -0,0 +1,645 @@
|
|||
-- Country Data Import SQL Script
|
||||
-- Generated from Lastenheft_Requirements Appendix A_Länder 1.csv
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. INSERT COUNTRY PROPERTY TYPES
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO `country_property_type`
|
||||
(`name`, `external_mapping_id`, `data_type`, `validation_rule`, `is_required`)
|
||||
VALUES
|
||||
('Customs Union', 'UNION', 'TEXT', NULL, FALSE),
|
||||
('Safety Stock [working days]', 'SAFETY_STOCK', 'INT', 'CHECK (CAST(property_value AS UNSIGNED) >= 0)', FALSE),
|
||||
('Air Freight Share [%]', 'AIR_SHARE', 'PERCENTAGE', 'CHECK (property_value REGEXP "^[0-9]+%$")', FALSE),
|
||||
('Wage Factor [%]', 'WAGE', 'PERCENTAGE', 'CHECK (property_value REGEXP "^[0-9]+%$")', FALSE);
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. INSERT COUNTRIES
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO `country` (`iso_code`, `region_code`, `is_deprecated`) VALUES
|
||||
('AD', 'EMEA', FALSE),
|
||||
('AE', 'EMEA', FALSE),
|
||||
('AF', 'EMEA', FALSE),
|
||||
('AG', 'LATAM', FALSE),
|
||||
('AI', 'LATAM', FALSE),
|
||||
('AL', 'EMEA', FALSE),
|
||||
('AM', 'EMEA', FALSE),
|
||||
('AO', 'EMEA', FALSE),
|
||||
('AQ', 'EMEA', FALSE),
|
||||
('AR', 'LATAM', FALSE),
|
||||
('AS', 'APAC', FALSE),
|
||||
('AT', 'EMEA', FALSE),
|
||||
('AU', 'APAC', FALSE),
|
||||
('AW', 'LATAM', FALSE),
|
||||
('AZ', 'EMEA', FALSE),
|
||||
('BA', 'EMEA', FALSE),
|
||||
('BB', 'LATAM', FALSE),
|
||||
('BD', 'EMEA', FALSE),
|
||||
('BE', 'EMEA', FALSE),
|
||||
('BF', 'EMEA', FALSE),
|
||||
('BG', 'EMEA', FALSE),
|
||||
('BH', 'EMEA', FALSE),
|
||||
('BI', 'EMEA', FALSE),
|
||||
('BJ', 'EMEA', FALSE),
|
||||
('BL', 'LATAM', FALSE),
|
||||
('BM', 'NAM', FALSE),
|
||||
('BN', 'APAC', FALSE),
|
||||
('BO', 'LATAM', FALSE),
|
||||
('BQ', 'LATAM', FALSE),
|
||||
('BR', 'LATAM', FALSE),
|
||||
('BS', 'LATAM', FALSE),
|
||||
('BT', 'APAC', FALSE),
|
||||
('BV', 'EMEA', FALSE),
|
||||
('BW', 'EMEA', FALSE),
|
||||
('BY', 'EMEA', FALSE),
|
||||
('BZ', 'LATAM', FALSE),
|
||||
('CA', 'NAM', FALSE),
|
||||
('CC', 'APAC', FALSE),
|
||||
('CD', 'EMEA', FALSE),
|
||||
('CF', 'EMEA', FALSE),
|
||||
('CG', 'EMEA', FALSE),
|
||||
('CH', 'EMEA', FALSE),
|
||||
('CI', 'EMEA', FALSE),
|
||||
('CK', 'APAC', FALSE),
|
||||
('CL', 'LATAM', FALSE),
|
||||
('CM', 'EMEA', FALSE),
|
||||
('CN', 'APAC', FALSE),
|
||||
('CO', 'LATAM', FALSE),
|
||||
('CR', 'LATAM', FALSE),
|
||||
('CU', 'LATAM', FALSE),
|
||||
('CV', 'EMEA', FALSE),
|
||||
('CW', 'LATAM', FALSE),
|
||||
('CX', 'APAC', FALSE),
|
||||
('CY', 'EMEA', FALSE),
|
||||
('CZ', 'EMEA', FALSE),
|
||||
('DE', 'EMEA', FALSE),
|
||||
('DJ', 'EMEA', FALSE),
|
||||
('DK', 'EMEA', FALSE),
|
||||
('DM', 'LATAM', FALSE),
|
||||
('DO', 'LATAM', FALSE),
|
||||
('DZ', 'EMEA', FALSE),
|
||||
('EC', 'LATAM', FALSE),
|
||||
('EE', 'EMEA', FALSE),
|
||||
('EG', 'EMEA', FALSE),
|
||||
('EH', 'EMEA', FALSE),
|
||||
('ER', 'EMEA', FALSE),
|
||||
('ES', 'EMEA', FALSE),
|
||||
('ET', 'EMEA', FALSE),
|
||||
('FI', 'EMEA', FALSE),
|
||||
('FJ', 'APAC', FALSE),
|
||||
('FK', 'LATAM', FALSE),
|
||||
('FM', 'APAC', FALSE),
|
||||
('FO', 'EMEA', FALSE),
|
||||
('FR', 'EMEA', FALSE),
|
||||
('GA', 'EMEA', FALSE),
|
||||
('GB', 'EMEA', FALSE),
|
||||
('GD', 'LATAM', FALSE),
|
||||
('GE', 'EMEA', FALSE),
|
||||
('GF', 'LATAM', FALSE),
|
||||
('GG', 'EMEA', FALSE),
|
||||
('GH', 'EMEA', FALSE),
|
||||
('GI', 'EMEA', FALSE),
|
||||
('GL', 'NAM', FALSE),
|
||||
('GM', 'EMEA', FALSE),
|
||||
('GN', 'EMEA', FALSE),
|
||||
('GP', 'LATAM', FALSE),
|
||||
('GQ', 'EMEA', FALSE),
|
||||
('GR', 'EMEA', FALSE),
|
||||
('GS', 'LATAM', FALSE),
|
||||
('GT', 'LATAM', FALSE),
|
||||
('GU', 'APAC', FALSE),
|
||||
('GW', 'EMEA', FALSE),
|
||||
('GY', 'LATAM', FALSE),
|
||||
('HK', 'APAC', FALSE),
|
||||
('HM', 'APAC', FALSE),
|
||||
('HN', 'LATAM', FALSE),
|
||||
('HR', 'EMEA', FALSE),
|
||||
('HT', 'LATAM', FALSE),
|
||||
('HU', 'EMEA', FALSE),
|
||||
('ID', 'APAC', FALSE),
|
||||
('IE', 'EMEA', FALSE),
|
||||
('IL', 'EMEA', FALSE),
|
||||
('IM', 'EMEA', FALSE),
|
||||
('IN', 'APAC', FALSE),
|
||||
('IO', 'APAC', FALSE),
|
||||
('IQ', 'EMEA', FALSE),
|
||||
('IR', 'EMEA', FALSE),
|
||||
('IS', 'EMEA', FALSE),
|
||||
('IT', 'EMEA', FALSE),
|
||||
('JE', 'EMEA', FALSE),
|
||||
('JM', 'LATAM', FALSE),
|
||||
('JO', 'EMEA', FALSE),
|
||||
('JP', 'APAC', FALSE),
|
||||
('KE', 'EMEA', FALSE),
|
||||
('KG', 'EMEA', FALSE),
|
||||
('KH', 'APAC', FALSE),
|
||||
('KI', 'APAC', FALSE),
|
||||
('KM', 'EMEA', FALSE),
|
||||
('KN', 'LATAM', FALSE),
|
||||
('KP', 'APAC', FALSE),
|
||||
('KR', 'APAC', FALSE),
|
||||
('KW', 'EMEA', FALSE),
|
||||
('KY', 'LATAM', FALSE),
|
||||
('KZ', 'EMEA', FALSE),
|
||||
('LA', 'APAC', FALSE),
|
||||
('LB', 'EMEA', FALSE),
|
||||
('LC', 'LATAM', FALSE),
|
||||
('LI', 'EMEA', FALSE),
|
||||
('LK', 'APAC', FALSE),
|
||||
('LR', 'EMEA', FALSE),
|
||||
('LS', 'EMEA', FALSE),
|
||||
('LT', 'EMEA', FALSE),
|
||||
('LU', 'EMEA', FALSE),
|
||||
('LV', 'EMEA', FALSE),
|
||||
('LY', 'EMEA', FALSE),
|
||||
('MA', 'EMEA', FALSE),
|
||||
('MC', 'EMEA', FALSE),
|
||||
('MD', 'EMEA', FALSE),
|
||||
('ME', 'EMEA', FALSE),
|
||||
('MF', 'LATAM', FALSE),
|
||||
('MG', 'EMEA', FALSE),
|
||||
('MH', 'APAC', FALSE),
|
||||
('MK', 'EMEA', FALSE),
|
||||
('ML', 'EMEA', FALSE),
|
||||
('MM', 'APAC', FALSE),
|
||||
('MN', 'APAC', FALSE),
|
||||
('MO', 'APAC', FALSE),
|
||||
('MP', 'APAC', FALSE),
|
||||
('MQ', 'LATAM', FALSE),
|
||||
('MR', 'EMEA', FALSE),
|
||||
('MS', 'LATAM', FALSE),
|
||||
('MT', 'EMEA', FALSE),
|
||||
('MU', 'EMEA', FALSE),
|
||||
('MV', 'APAC', FALSE),
|
||||
('MW', 'EMEA', FALSE),
|
||||
('MX', 'LATAM', FALSE),
|
||||
('MY', 'APAC', FALSE),
|
||||
('MZ', 'EMEA', FALSE),
|
||||
('NA', 'EMEA', FALSE),
|
||||
('NC', 'APAC', FALSE),
|
||||
('NE', 'EMEA', FALSE),
|
||||
('NF', 'APAC', FALSE),
|
||||
('NG', 'EMEA', FALSE),
|
||||
('NI', 'LATAM', FALSE),
|
||||
('NL', 'EMEA', FALSE),
|
||||
('NO', 'EMEA', FALSE),
|
||||
('NP', 'APAC', FALSE),
|
||||
('NR', 'APAC', FALSE),
|
||||
('NU', 'APAC', FALSE),
|
||||
('NZ', 'APAC', FALSE),
|
||||
('OM', 'EMEA', FALSE),
|
||||
('PA', 'LATAM', FALSE),
|
||||
('PE', 'LATAM', FALSE),
|
||||
('PF', 'APAC', FALSE),
|
||||
('PG', 'APAC', FALSE),
|
||||
('PH', 'APAC', FALSE),
|
||||
('PK', 'APAC', FALSE),
|
||||
('PL', 'EMEA', FALSE),
|
||||
('PM', 'NAM', FALSE),
|
||||
('PN', 'APAC', FALSE),
|
||||
('PR', 'LATAM', FALSE),
|
||||
('PS', 'EMEA', FALSE),
|
||||
('PT', 'EMEA', FALSE),
|
||||
('PW', 'APAC', FALSE),
|
||||
('PY', 'LATAM', FALSE),
|
||||
('QA', 'EMEA', FALSE),
|
||||
('RE', 'EMEA', FALSE),
|
||||
('RO', 'EMEA', FALSE),
|
||||
('RS', 'EMEA', FALSE),
|
||||
('RU', 'EMEA', FALSE),
|
||||
('RW', 'EMEA', FALSE),
|
||||
('SA', 'EMEA', FALSE),
|
||||
('SB', 'APAC', FALSE),
|
||||
('SC', 'EMEA', FALSE),
|
||||
('SD', 'EMEA', FALSE),
|
||||
('SE', 'EMEA', FALSE),
|
||||
('SG', 'APAC', FALSE),
|
||||
('SH', 'EMEA', FALSE),
|
||||
('SI', 'EMEA', FALSE),
|
||||
('SJ', 'EMEA', FALSE),
|
||||
('SK', 'EMEA', FALSE),
|
||||
('SL', 'EMEA', FALSE),
|
||||
('SM', 'EMEA', FALSE),
|
||||
('SN', 'EMEA', FALSE),
|
||||
('SO', 'EMEA', FALSE),
|
||||
('SR', 'LATAM', FALSE),
|
||||
('SS', 'EMEA', FALSE),
|
||||
('ST', 'EMEA', FALSE),
|
||||
('SV', 'LATAM', FALSE),
|
||||
('SX', 'LATAM', FALSE),
|
||||
('SY', 'EMEA', FALSE),
|
||||
('SZ', 'EMEA', FALSE),
|
||||
('TC', 'LATAM', FALSE),
|
||||
('TD', 'EMEA', FALSE),
|
||||
('TF', 'EMEA', FALSE),
|
||||
('TG', 'EMEA', FALSE),
|
||||
('TH', 'APAC', FALSE),
|
||||
('TJ', 'EMEA', FALSE),
|
||||
('TK', 'APAC', FALSE),
|
||||
('TL', 'APAC', FALSE),
|
||||
('TM', 'EMEA', FALSE),
|
||||
('TN', 'EMEA', FALSE),
|
||||
('TO', 'APAC', FALSE),
|
||||
('TR', 'EMEA', FALSE),
|
||||
('TT', 'LATAM', FALSE),
|
||||
('TV', 'APAC', FALSE),
|
||||
('TW', 'APAC', FALSE),
|
||||
('TZ', 'EMEA', FALSE),
|
||||
('UA', 'EMEA', FALSE),
|
||||
('UG', 'EMEA', FALSE),
|
||||
('UM', 'APAC', FALSE),
|
||||
('US', 'NAM', FALSE),
|
||||
('UY', 'LATAM', FALSE),
|
||||
('UZ', 'EMEA', FALSE),
|
||||
('VA', 'EMEA', FALSE),
|
||||
('VC', 'LATAM', FALSE),
|
||||
('VE', 'LATAM', FALSE),
|
||||
('VG', 'LATAM', FALSE),
|
||||
('VI', 'LATAM', FALSE),
|
||||
('VN', 'APAC', FALSE),
|
||||
('VU', 'APAC', FALSE),
|
||||
('WF', 'APAC', FALSE),
|
||||
('WS', 'APAC', FALSE),
|
||||
('YE', 'EMEA', FALSE),
|
||||
('YT', 'EMEA', FALSE),
|
||||
('ZA', 'EMEA', FALSE),
|
||||
('ZM', 'EMEA', FALSE),
|
||||
('ZW', 'EMEA', FALSE);
|
||||
|
||||
-- =============================================================================
|
||||
-- 3. INSERT COUNTRY PROPERTIES
|
||||
-- =============================================================================
|
||||
|
||||
-- Note: Uses the currently valid property set (state = 'VALID' and within date range)
|
||||
-- If no valid property set exists, these inserts will fail with NULL constraint violation
|
||||
-- To create a new property set if none exists, uncomment the following:
|
||||
-- INSERT INTO `property_set` (`start_date`, `state`) VALUES (NOW(), 'VALID');
|
||||
|
||||
-- Note: Using current valid property set
|
||||
-- Customs Union Properties (only for EU countries)
|
||||
INSERT INTO `country_property`
|
||||
(`country_id`, `country_property_type_id`, `property_set_id`, `property_value`)
|
||||
SELECT
|
||||
c.id,
|
||||
cpt.id,
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
'EU'
|
||||
FROM `country` c, `country_property_type` cpt
|
||||
WHERE c.iso_code IN ('AT', 'BE', 'BG', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK')
|
||||
AND cpt.external_mapping_id = 'UNION';
|
||||
|
||||
-- Safety Stock Properties
|
||||
INSERT INTO `country_property`
|
||||
(`country_id`, `country_property_type_id`, `property_set_id`, `property_value`)
|
||||
SELECT
|
||||
c.id,
|
||||
cpt.id,
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
CASE c.iso_code
|
||||
WHEN 'AD' THEN '15'
|
||||
WHEN 'AE' THEN '20'
|
||||
WHEN 'AF' THEN '30'
|
||||
WHEN 'AG' THEN '55'
|
||||
WHEN 'AI' THEN '55'
|
||||
WHEN 'AL' THEN '15'
|
||||
WHEN 'AM' THEN '15'
|
||||
WHEN 'AO' THEN '15'
|
||||
WHEN 'AQ' THEN '55'
|
||||
WHEN 'AR' THEN '55'
|
||||
WHEN 'AS' THEN '55'
|
||||
WHEN 'AT' THEN '10'
|
||||
WHEN 'AU' THEN '55'
|
||||
WHEN 'AW' THEN '55'
|
||||
WHEN 'AZ' THEN '15'
|
||||
WHEN 'BA' THEN '15'
|
||||
WHEN 'BB' THEN '55'
|
||||
WHEN 'BD' THEN '30'
|
||||
WHEN 'BE' THEN '10'
|
||||
WHEN 'BF' THEN '15'
|
||||
WHEN 'BG' THEN '10'
|
||||
WHEN 'BH' THEN '20'
|
||||
WHEN 'BI' THEN '15'
|
||||
WHEN 'BJ' THEN '15'
|
||||
WHEN 'BL' THEN '55'
|
||||
WHEN 'BM' THEN '55'
|
||||
WHEN 'BN' THEN '55'
|
||||
WHEN 'BO' THEN '55'
|
||||
WHEN 'BQ' THEN '55'
|
||||
WHEN 'BR' THEN '55'
|
||||
WHEN 'BS' THEN '55'
|
||||
WHEN 'BT' THEN '55'
|
||||
WHEN 'BV' THEN '55'
|
||||
WHEN 'BW' THEN '15'
|
||||
WHEN 'BY' THEN '15'
|
||||
WHEN 'BZ' THEN '55'
|
||||
WHEN 'CA' THEN '55'
|
||||
WHEN 'CC' THEN '55'
|
||||
WHEN 'CD' THEN '15'
|
||||
WHEN 'CF' THEN '15'
|
||||
WHEN 'CG' THEN '15'
|
||||
WHEN 'CH' THEN '10'
|
||||
WHEN 'CI' THEN '15'
|
||||
WHEN 'CK' THEN '55'
|
||||
WHEN 'CL' THEN '55'
|
||||
WHEN 'CM' THEN '15'
|
||||
WHEN 'CN' THEN '55'
|
||||
WHEN 'CO' THEN '55'
|
||||
WHEN 'CR' THEN '55'
|
||||
WHEN 'CU' THEN '55'
|
||||
WHEN 'CV' THEN '15'
|
||||
WHEN 'CW' THEN '55'
|
||||
WHEN 'CX' THEN '55'
|
||||
WHEN 'CY' THEN '10'
|
||||
WHEN 'CZ' THEN '10'
|
||||
WHEN 'DE' THEN '10'
|
||||
WHEN 'DJ' THEN '15'
|
||||
WHEN 'DK' THEN '10'
|
||||
WHEN 'DM' THEN '55'
|
||||
WHEN 'DO' THEN '55'
|
||||
WHEN 'DZ' THEN '15'
|
||||
WHEN 'EC' THEN '55'
|
||||
WHEN 'EE' THEN '10'
|
||||
WHEN 'EG' THEN '15'
|
||||
WHEN 'EH' THEN '15'
|
||||
WHEN 'ER' THEN '15'
|
||||
WHEN 'ES' THEN '10'
|
||||
WHEN 'ET' THEN '15'
|
||||
WHEN 'FI' THEN '10'
|
||||
WHEN 'FJ' THEN '55'
|
||||
WHEN 'FK' THEN '55'
|
||||
WHEN 'FM' THEN '55'
|
||||
WHEN 'FO' THEN '10'
|
||||
WHEN 'FR' THEN '10'
|
||||
WHEN 'GA' THEN '15'
|
||||
WHEN 'GB' THEN '10'
|
||||
WHEN 'GD' THEN '55'
|
||||
WHEN 'GE' THEN '15'
|
||||
WHEN 'GF' THEN '55'
|
||||
WHEN 'GG' THEN '10'
|
||||
WHEN 'GH' THEN '15'
|
||||
WHEN 'GI' THEN '10'
|
||||
WHEN 'GL' THEN '55'
|
||||
WHEN 'GM' THEN '15'
|
||||
WHEN 'GN' THEN '15'
|
||||
WHEN 'GP' THEN '55'
|
||||
WHEN 'GQ' THEN '15'
|
||||
WHEN 'GR' THEN '10'
|
||||
WHEN 'GS' THEN '55'
|
||||
WHEN 'GT' THEN '55'
|
||||
WHEN 'GU' THEN '55'
|
||||
WHEN 'GW' THEN '15'
|
||||
WHEN 'GY' THEN '55'
|
||||
WHEN 'HK' THEN '55'
|
||||
WHEN 'HM' THEN '55'
|
||||
WHEN 'HN' THEN '55'
|
||||
WHEN 'HR' THEN '10'
|
||||
WHEN 'HT' THEN '55'
|
||||
WHEN 'HU' THEN '10'
|
||||
WHEN 'ID' THEN '55'
|
||||
WHEN 'IE' THEN '10'
|
||||
WHEN 'IL' THEN '15'
|
||||
WHEN 'IM' THEN '10'
|
||||
WHEN 'IN' THEN '55'
|
||||
WHEN 'IO' THEN '55'
|
||||
WHEN 'IQ' THEN '30'
|
||||
WHEN 'IR' THEN '30'
|
||||
WHEN 'IS' THEN '10'
|
||||
WHEN 'IT' THEN '10'
|
||||
WHEN 'JE' THEN '10'
|
||||
WHEN 'JM' THEN '55'
|
||||
WHEN 'JO' THEN '15'
|
||||
WHEN 'JP' THEN '55'
|
||||
WHEN 'KE' THEN '15'
|
||||
WHEN 'KG' THEN '15'
|
||||
WHEN 'KH' THEN '55'
|
||||
WHEN 'KI' THEN '55'
|
||||
WHEN 'KM' THEN '15'
|
||||
WHEN 'KN' THEN '55'
|
||||
WHEN 'KP' THEN '55'
|
||||
WHEN 'KR' THEN '55'
|
||||
WHEN 'KW' THEN '20'
|
||||
WHEN 'KY' THEN '55'
|
||||
WHEN 'KZ' THEN '15'
|
||||
WHEN 'LA' THEN '55'
|
||||
WHEN 'LB' THEN '15'
|
||||
WHEN 'LC' THEN '55'
|
||||
WHEN 'LI' THEN '10'
|
||||
WHEN 'LK' THEN '55'
|
||||
WHEN 'LR' THEN '15'
|
||||
WHEN 'LS' THEN '15'
|
||||
WHEN 'LT' THEN '10'
|
||||
WHEN 'LU' THEN '10'
|
||||
WHEN 'LV' THEN '10'
|
||||
WHEN 'LY' THEN '15'
|
||||
WHEN 'MA' THEN '15'
|
||||
WHEN 'MC' THEN '10'
|
||||
WHEN 'MD' THEN '15'
|
||||
WHEN 'ME' THEN '15'
|
||||
WHEN 'MF' THEN '55'
|
||||
WHEN 'MG' THEN '15'
|
||||
WHEN 'MH' THEN '55'
|
||||
WHEN 'MK' THEN '15'
|
||||
WHEN 'ML' THEN '15'
|
||||
WHEN 'MM' THEN '55'
|
||||
WHEN 'MN' THEN '55'
|
||||
WHEN 'MO' THEN '55'
|
||||
WHEN 'MP' THEN '55'
|
||||
WHEN 'MQ' THEN '55'
|
||||
WHEN 'MR' THEN '15'
|
||||
WHEN 'MS' THEN '55'
|
||||
WHEN 'MT' THEN '10'
|
||||
WHEN 'MU' THEN '15'
|
||||
WHEN 'MV' THEN '55'
|
||||
WHEN 'MW' THEN '15'
|
||||
WHEN 'MX' THEN '55'
|
||||
WHEN 'MY' THEN '55'
|
||||
WHEN 'MZ' THEN '15'
|
||||
WHEN 'NA' THEN '15'
|
||||
WHEN 'NC' THEN '55'
|
||||
WHEN 'NE' THEN '15'
|
||||
WHEN 'NF' THEN '55'
|
||||
WHEN 'NG' THEN '15'
|
||||
WHEN 'NI' THEN '55'
|
||||
WHEN 'NL' THEN '10'
|
||||
WHEN 'NO' THEN '10'
|
||||
WHEN 'NP' THEN '55'
|
||||
WHEN 'NR' THEN '55'
|
||||
WHEN 'NU' THEN '55'
|
||||
WHEN 'NZ' THEN '55'
|
||||
WHEN 'OM' THEN '20'
|
||||
WHEN 'PA' THEN '55'
|
||||
WHEN 'PE' THEN '55'
|
||||
WHEN 'PF' THEN '55'
|
||||
WHEN 'PG' THEN '55'
|
||||
WHEN 'PH' THEN '55'
|
||||
WHEN 'PK' THEN '30'
|
||||
WHEN 'PL' THEN '10'
|
||||
WHEN 'PM' THEN '55'
|
||||
WHEN 'PN' THEN '55'
|
||||
WHEN 'PR' THEN '55'
|
||||
WHEN 'PS' THEN '15'
|
||||
WHEN 'PT' THEN '10'
|
||||
WHEN 'PW' THEN '55'
|
||||
WHEN 'PY' THEN '55'
|
||||
WHEN 'QA' THEN '20'
|
||||
WHEN 'RE' THEN '15'
|
||||
WHEN 'RO' THEN '10'
|
||||
WHEN 'RS' THEN '15'
|
||||
WHEN 'RU' THEN '15'
|
||||
WHEN 'RW' THEN '15'
|
||||
WHEN 'SA' THEN '20'
|
||||
WHEN 'SB' THEN '55'
|
||||
WHEN 'SC' THEN '15'
|
||||
WHEN 'SD' THEN '15'
|
||||
WHEN 'SE' THEN '10'
|
||||
WHEN 'SG' THEN '55'
|
||||
WHEN 'SH' THEN '15'
|
||||
WHEN 'SI' THEN '10'
|
||||
WHEN 'SJ' THEN '10'
|
||||
WHEN 'SK' THEN '10'
|
||||
WHEN 'SL' THEN '15'
|
||||
WHEN 'SM' THEN '10'
|
||||
WHEN 'SN' THEN '15'
|
||||
WHEN 'SO' THEN '15'
|
||||
WHEN 'SR' THEN '55'
|
||||
WHEN 'SS' THEN '15'
|
||||
WHEN 'ST' THEN '15'
|
||||
WHEN 'SV' THEN '55'
|
||||
WHEN 'SX' THEN '55'
|
||||
WHEN 'SY' THEN '15'
|
||||
WHEN 'SZ' THEN '15'
|
||||
WHEN 'TC' THEN '55'
|
||||
WHEN 'TD' THEN '15'
|
||||
WHEN 'TF' THEN '55'
|
||||
WHEN 'TG' THEN '15'
|
||||
WHEN 'TH' THEN '55'
|
||||
WHEN 'TJ' THEN '15'
|
||||
WHEN 'TK' THEN '55'
|
||||
WHEN 'TL' THEN '55'
|
||||
WHEN 'TM' THEN '15'
|
||||
WHEN 'TN' THEN '15'
|
||||
WHEN 'TO' THEN '55'
|
||||
WHEN 'TR' THEN '15'
|
||||
WHEN 'TT' THEN '55'
|
||||
WHEN 'TV' THEN '55'
|
||||
WHEN 'TW' THEN '55'
|
||||
WHEN 'TZ' THEN '15'
|
||||
WHEN 'UA' THEN '15'
|
||||
WHEN 'UG' THEN '15'
|
||||
WHEN 'UM' THEN '55'
|
||||
WHEN 'US' THEN '55'
|
||||
WHEN 'UY' THEN '55'
|
||||
WHEN 'UZ' THEN '15'
|
||||
WHEN 'VA' THEN '10'
|
||||
WHEN 'VC' THEN '55'
|
||||
WHEN 'VE' THEN '55'
|
||||
WHEN 'VG' THEN '55'
|
||||
WHEN 'VI' THEN '55'
|
||||
WHEN 'VN' THEN '55'
|
||||
WHEN 'VU' THEN '55'
|
||||
WHEN 'WF' THEN '55'
|
||||
WHEN 'WS' THEN '55'
|
||||
WHEN 'YE' THEN '30'
|
||||
WHEN 'YT' THEN '15'
|
||||
WHEN 'ZA' THEN '15'
|
||||
WHEN 'ZM' THEN '15'
|
||||
WHEN 'ZW' THEN '15'
|
||||
END
|
||||
FROM `country` c, `country_property_type` cpt
|
||||
WHERE cpt.external_mapping_id = 'SAFETY_STOCK';
|
||||
|
||||
-- Air Freight Share Properties (all countries have 0%)
|
||||
INSERT INTO `country_property`
|
||||
(`country_id`, `country_property_type_id`, `property_set_id`, `property_value`)
|
||||
SELECT
|
||||
c.id,
|
||||
cpt.id,
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
'0'
|
||||
FROM `country` c, `country_property_type` cpt
|
||||
WHERE cpt.external_mapping_id = 'AIR_SHARE';
|
||||
|
||||
-- Wage Factor Properties (only for countries with defined values)
|
||||
INSERT INTO `country_property`
|
||||
(`country_id`, `country_property_type_id`, `property_set_id`, `property_value`)
|
||||
SELECT
|
||||
c.id,
|
||||
cpt.id,
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
CASE c.iso_code
|
||||
WHEN 'AT' THEN '99'
|
||||
WHEN 'BE' THEN '114'
|
||||
WHEN 'BG' THEN '23'
|
||||
WHEN 'CZ' THEN '44'
|
||||
WHEN 'DE' THEN '100'
|
||||
WHEN 'DK' THEN '116'
|
||||
WHEN 'EE' THEN '60'
|
||||
WHEN 'ES' THEN '90'
|
||||
WHEN 'FI' THEN '102'
|
||||
WHEN 'FR' THEN '105'
|
||||
WHEN 'GR' THEN '35'
|
||||
WHEN 'HR' THEN '31'
|
||||
WHEN 'HU' THEN '35'
|
||||
WHEN 'IE' THEN '97'
|
||||
WHEN 'IT' THEN '72'
|
||||
WHEN 'LT' THEN '36'
|
||||
WHEN 'LU' THEN '131'
|
||||
WHEN 'LV' THEN '33'
|
||||
WHEN 'MT' THEN '41'
|
||||
WHEN 'NL' THEN '105'
|
||||
WHEN 'PL' THEN '27'
|
||||
WHEN 'PT' THEN '41'
|
||||
WHEN 'RO' THEN '27'
|
||||
WHEN 'SE' THEN '94'
|
||||
WHEN 'SI' THEN '62'
|
||||
WHEN 'SK' THEN '42'
|
||||
END
|
||||
FROM `country` c, `country_property_type` cpt
|
||||
WHERE c.iso_code IN ('AT', 'BE', 'BG', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK')
|
||||
AND cpt.external_mapping_id = 'WAGE';
|
||||
|
||||
-- =============================================================================
|
||||
-- VERIFICATION QUERIES (Optional - for testing)
|
||||
-- =============================================================================
|
||||
|
||||
-- Verify country count
|
||||
-- SELECT COUNT(*) as total_countries FROM country;
|
||||
|
||||
-- Verify property types
|
||||
-- SELECT * FROM country_property_type;
|
||||
|
||||
-- Verify EU countries with all properties
|
||||
-- SELECT
|
||||
-- c.iso_code,
|
||||
-- c.region_code,
|
||||
-- MAX(CASE WHEN cpt.name = 'Customs Union' THEN cp.property_value END) as customs_union,
|
||||
-- MAX(CASE WHEN cpt.name = 'Safety Stock' THEN cp.property_value END) as safety_stock,
|
||||
-- MAX(CASE WHEN cpt.name = 'Air Freight Share' THEN cp.property_value END) as air_freight,
|
||||
-- MAX(CASE WHEN cpt.name = 'Wage Factor' THEN cp.property_value END) as wage_factor
|
||||
-- FROM country c
|
||||
-- JOIN country_property cp ON c.id = cp.country_id
|
||||
-- JOIN country_property_type cpt ON cp.country_property_type_id = cpt.id
|
||||
-- WHERE c.iso_code IN ('DE', 'FR', 'AT', 'BE', 'NL')
|
||||
-- GROUP BY c.id, c.iso_code, c.region_code
|
||||
-- ORDER BY c.iso_code;
|
||||
23310
src/main/resources/data-countrymatrixrate.sql
Normal file
23310
src/main/resources/data-countrymatrixrate.sql
Normal file
File diff suppressed because it is too large
Load diff
1217997
src/main/resources/data-material.sql
Normal file
1217997
src/main/resources/data-material.sql
Normal file
File diff suppressed because it is too large
Load diff
1332
src/main/resources/data-nodes.sql
Normal file
1332
src/main/resources/data-nodes.sql
Normal file
File diff suppressed because it is too large
Load diff
1182
src/main/resources/data-predecessor-nodes.sql
Normal file
1182
src/main/resources/data-predecessor-nodes.sql
Normal file
File diff suppressed because it is too large
Load diff
518
src/main/resources/data-properties.sql
Normal file
518
src/main/resources/data-properties.sql
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
-- ===================================================
|
||||
-- INSERT Statements für system_property_type
|
||||
-- Mapping: external mapping id -> external_mapping_id
|
||||
-- Description -> name
|
||||
-- ===================================================
|
||||
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (1, 'Annual working days', 'WORKDAYS', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (2, 'Interest rate inventory [%]', 'INTEREST_RATE', 'PERCENTAGE', 'RANGE_0_1');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (3, 'FCA fee [%]', 'FCA_FEE', 'PERCENTAGE', 'RANGE_0_1');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (4, 'Default customs duty [%]', 'TARIFF_RATE', 'PERCENTAGE', 'RANGE_0_1');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (5, 'Customs clearance fee per import & HS code', 'CUSTOM_FEE', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (6, 'Standard-Report Format', 'REPORTING', 'TEXT', 'MAX_LENGTH_100');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (7, '40''', 'FEU', 'BOOLEAN', 'YES_NO');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (8, '20''', 'TEU', 'BOOLEAN', 'YES_NO');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (9, '40''HC', 'FEU_HQ', 'BOOLEAN', 'YES_NO');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (10, '20''HC', 'TEU_HQ', 'BOOLEAN', 'YES_NO');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (11, 'Container utilization in mixed containers [%]', 'CONTAINER_UTIL', 'PERCENTAGE', 'RANGE_0_1');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (12, 'Truck utilization road transport EMEA [%]', 'TRUCK_UTIL', 'PERCENTAGE', 'RANGE_0_1');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (13, 'Max validity of container freight rates [days]', 'VALID_DAYS', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (14, 'Metropolition region size (diameter) [km]', 'RADIUS_REGION', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (15, 'Min delivery frequency / year for containtrer transports', 'FREQ_MIN', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (16, 'Max delivery frequency / year for containtrer transports', 'FREQ_MAX', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (17, 'Max load of 20'' container [kg]', 'TEU_LOAD', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (18, 'Max load of 40'' container [kg]', 'FEU_LOAD', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (19, 'Pre-carriage [EUR/kg]', 'AIR_PRECARRIAGE', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (20, 'Pre-carriage handling [EUR]', 'AIR_HANDLING', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (21, 'Main carriage [EUR/kg]', 'AIR_MAINCARRIAGE', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (22, 'Hand over fee [EUR]', 'AIR_HANDOVER_FEE', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (23, 'Customs clearance fee [EUR]', 'AIR_CUSTOM_FEE', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (24, 'On-carriage [EUR/kg]', 'AIR_ONCARRIAGE', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (25, 'Terminal handling fee [EUR/kg]', 'AIR_TERMINAL_FEE', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (26, 'GR handling KLT [EUR/HU]', 'KLT_HANDLING', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (27, 'GR handling GLT [EUR/HU]', 'GLT_HANDLING', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (28, 'GLT/KLT booking & document handling [EUR/GR]', 'BOOKING', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (29, 'GLT release from storage [EUR/GLT release]', 'GLT_RELEASE', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (30, 'KLT release from storage [EUR/KLT release]', 'KLT_RELEASE', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (31, 'GLT dispatch [EUR/GLT dispatch]', 'GLT_DISPATCH', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (32, 'KLT dispacth [EUR/KLT dispatch]', 'KLT_DISPATCH', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (33, 'Repacking KLT, HU <15kg [EUR/HU]', 'KLT_REPACK_S', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (34, 'Repacking KLT, HU >=15kg [EUR/HU]', 'KLT_REPACK_M', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (35, 'Repacking GLT, HU <15kg [EUR/HU]', 'GLT_REPACK_S', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (36, 'Repacking GLT, HU 15 - 2000kg [EUR/HU]', 'GLT_REPACK_M', 'CURRENCY', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (37, 'Repacking GLT, HU > 2000kg [EUR/HU]', 'GLT_REPACK_L', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (38, 'GLT disposal [EUR/GLT]', 'DISPOSAL', 'INT', 'MIN_0');
|
||||
INSERT INTO system_property_type (id, name, external_mapping_id, data_type, validation_rule) VALUES (39, 'Space costs / m3 per night [EUR/m3]', 'SPACE_COST', 'CURRENCY', 'MIN_0');
|
||||
|
||||
-- ===================================================
|
||||
-- INSERT Statements für system_property
|
||||
-- Verwendung von Subqueries für dynamische ID-Ermittlung
|
||||
-- ===================================================
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'WORKDAYS'),
|
||||
'210'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'INTEREST_RATE'),
|
||||
'0.12'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'FCA_FEE'),
|
||||
'0.002'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'TARIFF_RATE'),
|
||||
'0.03'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'CUSTOM_FEE'),
|
||||
'35'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'REPORTING'),
|
||||
'MEK_B'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'FEU'),
|
||||
'true'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'TEU'),
|
||||
'true'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'FEU_HQ'),
|
||||
'true'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'TEU_HQ'),
|
||||
'false'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'CONTAINER_UTIL'),
|
||||
'0.7'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'TRUCK_UTIL'),
|
||||
'0.7'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'VALID_DAYS'),
|
||||
'60'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'RADIUS_REGION'),
|
||||
'20'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'FREQ_MIN'),
|
||||
'3'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'FREQ_MAX'),
|
||||
'50'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'TEU_LOAD'),
|
||||
'20000'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'FEU_LOAD'),
|
||||
'21000'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'AIR_PRECARRIAGE'),
|
||||
'0.1'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'AIR_HANDLING'),
|
||||
'80'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'AIR_MAINCARRIAGE'),
|
||||
'3.5'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'AIR_HANDOVER_FEE'),
|
||||
'35'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'AIR_CUSTOM_FEE'),
|
||||
'45'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'AIR_ONCARRIAGE'),
|
||||
'0.2'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'AIR_TERMINAL_FEE'),
|
||||
'0.2'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'KLT_HANDLING'),
|
||||
'0.71'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'GLT_HANDLING'),
|
||||
'3.5'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'BOOKING'),
|
||||
'3.5'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'GLT_RELEASE'),
|
||||
'2.23'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'KLT_RELEASE'),
|
||||
'1.12'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'GLT_DISPATCH'),
|
||||
'1.61'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'KLT_DISPATCH'),
|
||||
'0.333'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'KLT_REPACK_S'),
|
||||
'2.08'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'KLT_REPACK_M'),
|
||||
'3.02'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'GLT_REPACK_S'),
|
||||
'3.02'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'GLT_REPACK_M'),
|
||||
'7.76'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'GLT_REPACK_L'),
|
||||
'14'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'DISPOSAL'),
|
||||
'6'
|
||||
);
|
||||
|
||||
INSERT INTO system_property (property_set_id, system_property_type_id, property_value)
|
||||
VALUES (
|
||||
(SELECT ps.id FROM `property_set` ps
|
||||
WHERE ps.state = 'VALID'
|
||||
AND ps.start_date <= NOW()
|
||||
AND (ps.end_date IS NULL OR ps.end_date > NOW())
|
||||
ORDER BY ps.start_date DESC
|
||||
LIMIT 1),
|
||||
(SELECT spt.id FROM system_property_type spt WHERE spt.external_mapping_id = 'SPACE_COST'),
|
||||
'0.2630136986'
|
||||
);
|
||||
|
|
@ -378,6 +378,7 @@ CREATE TABLE IF NOT EXISTS premise_destination
|
|||
destination_node_id INT NOT NULL,
|
||||
is_d2d BOOLEAN DEFAULT FALSE,
|
||||
rate_d2d DECIMAL(15, 2) DEFAULT NULL,
|
||||
lead_time_d2d INT UNSIGNED NOT NULL,
|
||||
repacking_cost DECIMAL(15, 2) DEFAULT NULL,
|
||||
handling_cost DECIMAL(15, 2) DEFAULT NULL,
|
||||
disposal_cost DECIMAL(15, 2) DEFAULT NULL,
|
||||
|
|
@ -432,7 +433,7 @@ CREATE TABLE IF NOT EXISTS premise_route_section
|
|||
list_position INT NOT NULL,
|
||||
transport_type CHAR(16) CHECK (transport_type IN
|
||||
('RAIL', 'SEA', 'ROAD', 'POST-RUN')),
|
||||
rate_type CHAR(16) CHECK (transport_type IN
|
||||
rate_type CHAR(16) CHECK (rate_type IN
|
||||
('CONTAINER', 'MATRIX')),
|
||||
is_pre_run BOOLEAN DEFAULT FALSE,
|
||||
is_main_run BOOLEAN DEFAULT FALSE,
|
||||
|
|
@ -474,20 +475,20 @@ CREATE TABLE IF NOT EXISTS calculation_job_destination
|
|||
calculation_job_id INT NOT NULL,
|
||||
premise_destination_id INT NOT NULL,
|
||||
shipping_frequency INT UNSIGNED COMMENT 'annual shipping frequency',
|
||||
total_cost DECIMAL(15, 2) COMMENT 'aka MEK_B in EUR',
|
||||
annual_amount DECIMAL(15, 2) COMMENT 'annual quantity for this destinations',
|
||||
total_cost DECIMAL(15, 2) COMMENT 'aka MEK_B in EUR (excl. Airfreight)',
|
||||
annual_amount DECIMAL(15, 2) COMMENT 'annual quantity for this destinations in pieces',
|
||||
-- risk
|
||||
annual_risk_cost DECIMAL(15, 2) NOT NULL COMMENT 'complete calculation with globally stored worst case container rates',
|
||||
annual_chance_cost DECIMAL(15, 2) NOT NULL COMMENT 'complete calculation with globally stored best case container rates',
|
||||
annual_risk_cost DECIMAL(15, 2) NOT NULL COMMENT 'complete calculation with globally stored worst case container rates (excl. Airfreight)',
|
||||
annual_chance_cost DECIMAL(15, 2) NOT NULL COMMENT 'complete calculation with globally stored best case container rates (excl. Airfreight)',
|
||||
-- handling
|
||||
is_small_unit BOOLEAN DEFAULT FALSE COMMENT 'small unit equals KLT, volume of a handling unit is smaller than 0.08 cbm ',
|
||||
is_small_unit BOOLEAN DEFAULT FALSE COMMENT 'small unit equals KLT, volume of a handling unit is smaller than 0.08 cbm ',
|
||||
annual_repacking_cost DECIMAL(15, 2) NOT NULL,
|
||||
annual_handling_cost DECIMAL(15, 2) NOT NULL,
|
||||
annual_disposal_cost DECIMAL(15, 2) NOT NULL,
|
||||
-- inventory
|
||||
operational_stock DECIMAL(15, 2) NOT NULL COMMENT 'operational stock in single pieces',
|
||||
safety_stock DECIMAL(15, 2) NOT NULL COMMENT 'safety stock in single pieces',
|
||||
stocked_inventory DECIMAL(15, 2) NOT NULL COMMENT 'sum of operational and safety stock ?!',
|
||||
stocked_inventory DECIMAL(15, 2) NOT NULL COMMENT 'sum of operational and safety stock',
|
||||
in_transport_stock DECIMAL(15, 2) NOT NULL,
|
||||
stock_before_payment DECIMAL(15, 2) NOT NULL,
|
||||
annual_capital_cost DECIMAL(15, 2) NOT NULL,
|
||||
|
|
@ -504,15 +505,18 @@ CREATE TABLE IF NOT EXISTS calculation_job_destination
|
|||
air_freight_weight DECIMAL(15, 2) NOT NULL,
|
||||
annual_air_freight_cost DECIMAL(15, 2) NOT NULL,
|
||||
-- transportation
|
||||
transportation_type CHAR(8) CHECK (transportation_type IN
|
||||
is_d2d BOOLEAN DEFAULT FALSE,
|
||||
rate_d2d DECIMAL(15, 2) DEFAULT NULL,
|
||||
container_type CHAR(8) CHECK (container_type IN
|
||||
('TEU', 'FEU', 'HC', 'TRUCK')),
|
||||
hu_per_layer INT UNSIGNED NOT NULL COMMENT 'number of handling units per layer',
|
||||
hu_count INT UNSIGNED NOT NULL COMMENT 'number of handling units int total',
|
||||
layer_structure JSON COMMENT 'json representation of a single layer',
|
||||
layer_count INT UNSIGNED NOT NULL COMMENT 'number of layers per full container or truck',
|
||||
transport_weight_exceeded BOOLEAN DEFAULT FALSE COMMENT 'limiting factor: TRUE if weight limited or FALSE if volume limited',
|
||||
transports_per_year DECIMAL(15, 2) NOT NULL COMMENT 'TODO: what is this?!',
|
||||
transport_weight_exceeded BOOLEAN DEFAULT FALSE COMMENT 'limiting factor: TRUE if weight limited or FALSE if volume limited',
|
||||
annual_transportation_cost DECIMAL(15, 2) NOT NULL COMMENT 'total annual transportation costs in EUR',
|
||||
container_utilization DECIMAL(7, 4) NOT NULL,
|
||||
transit_time_in_days INT UNSIGNED NOT NULL,
|
||||
safety_stock_in_days INT UNSIGNED NOT NULL,
|
||||
-- material cost
|
||||
material_cost DECIMAL(15, 2) NOT NULL,
|
||||
fca_cost DECIMAL(15, 2) NOT NULL,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue