diff --git a/src/main/java/de/avatic/lcc/dto/calculation/RouteDTO.java b/src/main/java/de/avatic/lcc/dto/calculation/RouteDTO.java index 912bc3f..e5e6c0f 100644 --- a/src/main/java/de/avatic/lcc/dto/calculation/RouteDTO.java +++ b/src/main/java/de/avatic/lcc/dto/calculation/RouteDTO.java @@ -2,7 +2,7 @@ package de.avatic.lcc.dto.calculation; import com.fasterxml.jackson.annotation.JsonProperty; import de.avatic.lcc.dto.generic.NodeDTO; -import de.avatic.lcc.dto.generic.RouteType; +import de.avatic.lcc.dto.generic.TransportType; import java.util.List; @@ -10,7 +10,7 @@ public class RouteDTO { private Integer id; - private RouteType type; + private TransportType type; @JsonProperty("is_selected") private Boolean isSelected; @@ -32,11 +32,11 @@ public class RouteDTO { this.id = id; } - public RouteType getType() { + public TransportType getType() { return type; } - public void setType(RouteType type) { + public void setType(TransportType type) { this.type = type; } diff --git a/src/main/java/de/avatic/lcc/dto/configuration/rates/ContainerRateDTO.java b/src/main/java/de/avatic/lcc/dto/configuration/rates/ContainerRateDTO.java index aa16bec..cccbcab 100644 --- a/src/main/java/de/avatic/lcc/dto/configuration/rates/ContainerRateDTO.java +++ b/src/main/java/de/avatic/lcc/dto/configuration/rates/ContainerRateDTO.java @@ -2,7 +2,7 @@ package de.avatic.lcc.dto.configuration.rates; import com.fasterxml.jackson.annotation.JsonProperty; import de.avatic.lcc.dto.generic.NodeDTO; -import de.avatic.lcc.dto.generic.RouteType; +import de.avatic.lcc.dto.generic.TransportType; import de.avatic.lcc.dto.generic.ValidityPeriodDTO; import java.util.HashMap; @@ -14,7 +14,7 @@ public class ContainerRateDTO { private NodeDTO origin; private NodeDTO destination; - private RouteType type; + private TransportType type; private HashMap rates; @@ -47,11 +47,11 @@ public class ContainerRateDTO { this.destination = destination; } - public RouteType getType() { + public TransportType getType() { return type; } - public void setType(RouteType type) { + public void setType(TransportType type) { this.type = type; } diff --git a/src/main/java/de/avatic/lcc/dto/generic/RateType.java b/src/main/java/de/avatic/lcc/dto/generic/RateType.java new file mode 100644 index 0000000..b501d74 --- /dev/null +++ b/src/main/java/de/avatic/lcc/dto/generic/RateType.java @@ -0,0 +1,5 @@ +package de.avatic.lcc.dto.generic; + +public enum RateType { + MATRIX, CONTAINER, D2D +} diff --git a/src/main/java/de/avatic/lcc/dto/generic/RouteType.java b/src/main/java/de/avatic/lcc/dto/generic/RouteType.java deleted file mode 100644 index 5de9c66..0000000 --- a/src/main/java/de/avatic/lcc/dto/generic/RouteType.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.avatic.lcc.dto.generic; - -public enum RouteType { - RAIL, SEA, D2D, ROAD, POST_RUN -} diff --git a/src/main/java/de/avatic/lcc/dto/generic/TransportType.java b/src/main/java/de/avatic/lcc/dto/generic/TransportType.java new file mode 100644 index 0000000..6c57fd9 --- /dev/null +++ b/src/main/java/de/avatic/lcc/dto/generic/TransportType.java @@ -0,0 +1,5 @@ +package de.avatic.lcc.dto.generic; + +public enum TransportType { + RAIL, SEA, ROAD, POST_RUN +} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportContainerDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportContainerDTO.java deleted file mode 100644 index 54137a3..0000000 --- a/src/main/java/de/avatic/lcc/dto/report/ReportContainerDTO.java +++ /dev/null @@ -1,69 +0,0 @@ -package de.avatic.lcc.dto.report; - -import com.fasterxml.jackson.annotation.JsonProperty; -import de.avatic.lcc.dto.generic.ContainerType; - -public class ReportContainerDTO { - - private ContainerType type; - - private Number rate; - - @JsonProperty("unit_count") - private Number unitCount; - - @JsonProperty("weight_exceeded") - private Boolean weightExceeded; - - private Number utilization; - - private Boolean mixed; - - public ContainerType getType() { - return type; - } - - public void setType(ContainerType type) { - this.type = type; - } - - public Number getRate() { - return rate; - } - - public void setRate(Number rate) { - this.rate = rate; - } - - public Number getUnitCount() { - return unitCount; - } - - public void setUnitCount(Number unitCount) { - this.unitCount = unitCount; - } - - public Boolean getWeightExceeded() { - return weightExceeded; - } - - public void setWeightExceeded(Boolean weightExceeded) { - this.weightExceeded = weightExceeded; - } - - public Number getUtilization() { - return utilization; - } - - public void setUtilization(Number utilization) { - this.utilization = utilization; - } - - public Boolean getMixed() { - return mixed; - } - - public void setMixed(Boolean mixed) { - this.mixed = mixed; - } -} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportDTO.java index 07c4b84..0c16912 100644 --- a/src/main/java/de/avatic/lcc/dto/report/ReportDTO.java +++ b/src/main/java/de/avatic/lcc/dto/report/ReportDTO.java @@ -1,11 +1,15 @@ package de.avatic.lcc.dto.report; import com.fasterxml.jackson.annotation.JsonProperty; +import de.avatic.lcc.dto.generic.NodeDTO; +import java.util.List; import java.util.Map; public class ReportDTO { + NodeDTO supplier; + @JsonProperty("costs") public Map cost; @@ -13,8 +17,19 @@ public class ReportDTO { public Map risk; @JsonProperty("premises") - public ReportPremisesDTO premises; + public List destinations; + public NodeDTO getSupplier() { + return supplier; + } + + public void setSupplier(NodeDTO supplier) { + this.supplier = supplier; + } + + public void setDestinations(List destinations) { + this.destinations = destinations; + } public Map getCost() { return cost; @@ -32,11 +47,11 @@ public class ReportDTO { this.risk = risk; } - public ReportPremisesDTO getPremises() { - return premises; + public List getDestinations() { + return destinations; } - public void setPremises(ReportPremisesDTO premises) { - this.premises = premises; + public void setDestination(List destinations) { + this.destinations = destinations; } } diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportDestinationDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportDestinationDTO.java new file mode 100644 index 0000000..44402ac --- /dev/null +++ b/src/main/java/de/avatic/lcc/dto/report/ReportDestinationDTO.java @@ -0,0 +1,272 @@ +package de.avatic.lcc.dto.report; + +import com.fasterxml.jackson.annotation.JsonProperty; +import de.avatic.lcc.dto.generic.ContainerType; +import de.avatic.lcc.dto.generic.NodeDTO; +import de.avatic.lcc.model.utils.DimensionUnit; +import de.avatic.lcc.model.utils.WeightUnit; + +import java.util.List; + +public class ReportDestinationDTO { + + private Integer id; + + private NodeDTO destination; + private List sections; + + /* general */ + + @JsonProperty("annual_quantity") + private Integer annualQuantity; + + @JsonProperty("hs_code") + private String hsCode; + + @JsonProperty("tariff_rate") + private Number tariffRate; + + @JsonProperty("oversea_share") + private Double overseaShare; + + @JsonProperty("air_freight_share") + private Double airFreightShare; + + @JsonProperty("transport_time") + private Double transportTime; + + @JsonProperty("safety_stock") + private Double safetyStock; + + /* packaging */ + + private Double width; + + private Double height; + + private Double length; + + private Double weight; + + @JsonProperty("dimension_unit") + private DimensionUnit dimensionUnit; + + @JsonProperty("weight_unit") + private WeightUnit weightUnit; + + @JsonProperty("hu_unit_count") + private Integer huUnitCount; + + private Integer layer; + + /* container */ + + @JsonProperty("unit_count") + private Number unitCount; + + private Number utilization; + + @JsonProperty("container_type") + private ContainerType type; + + @JsonProperty("weight_exceeded") + private Boolean weightExceeded; + + @JsonProperty("container_rate") + private Number rate; + + private Boolean mixed; + + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public NodeDTO getDestination() { + return destination; + } + + public void setDestination(NodeDTO destination) { + this.destination = destination; + } + + public List getSections() { + return sections; + } + + public void setSections(List sections) { + this.sections = sections; + } + + public Integer getAnnualQuantity() { + return annualQuantity; + } + + public void setAnnualQuantity(Integer annualQuantity) { + this.annualQuantity = annualQuantity; + } + + public String getHsCode() { + return hsCode; + } + + public void setHsCode(String hsCode) { + this.hsCode = hsCode; + } + + public Number getTariffRate() { + return tariffRate; + } + + public void setTariffRate(Number tariffRate) { + this.tariffRate = tariffRate; + } + + public Double getOverseaShare() { + return overseaShare; + } + + public void setOverseaShare(Double overseaShare) { + this.overseaShare = overseaShare; + } + + public Double getAirFreightShare() { + return airFreightShare; + } + + public void setAirFreightShare(Double airFreightShare) { + this.airFreightShare = airFreightShare; + } + + public Double getTransportTime() { + return transportTime; + } + + public void setTransportTime(Double transportTime) { + this.transportTime = transportTime; + } + + public Double getSafetyStock() { + return safetyStock; + } + + public void setSafetyStock(Double safetyStock) { + this.safetyStock = safetyStock; + } + + public Double getWidth() { + return width; + } + + public void setWidth(Double width) { + this.width = width; + } + + public Double getHeight() { + return height; + } + + public void setHeight(Double height) { + this.height = height; + } + + public Double getLength() { + return length; + } + + public void setLength(Double length) { + this.length = length; + } + + public Double getWeight() { + return weight; + } + + public void setWeight(Double weight) { + this.weight = weight; + } + + public DimensionUnit getDimensionUnit() { + return dimensionUnit; + } + + public void setDimensionUnit(DimensionUnit dimensionUnit) { + this.dimensionUnit = dimensionUnit; + } + + public WeightUnit getWeightUnit() { + return weightUnit; + } + + public void setWeightUnit(WeightUnit weightUnit) { + this.weightUnit = weightUnit; + } + + public Integer getHuUnitCount() { + return huUnitCount; + } + + public void setHuUnitCount(Integer huUnitCount) { + this.huUnitCount = huUnitCount; + } + + public Integer getLayer() { + return layer; + } + + public void setLayer(Integer layer) { + this.layer = layer; + } + + public Number getUnitCount() { + return unitCount; + } + + public void setUnitCount(Number unitCount) { + this.unitCount = unitCount; + } + + public Number getUtilization() { + return utilization; + } + + public void setUtilization(Number utilization) { + this.utilization = utilization; + } + + public ContainerType getType() { + return type; + } + + public void setType(ContainerType type) { + this.type = type; + } + + public Boolean getWeightExceeded() { + return weightExceeded; + } + + public void setWeightExceeded(Boolean weightExceeded) { + this.weightExceeded = weightExceeded; + } + + public Number getRate() { + return rate; + } + + public void setRate(Number rate) { + this.rate = rate; + } + + public Boolean getMixed() { + return mixed; + } + + public void setMixed(Boolean mixed) { + this.mixed = mixed; + } +} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportPackagingDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportPackagingDTO.java deleted file mode 100644 index ce07066..0000000 --- a/src/main/java/de/avatic/lcc/dto/report/ReportPackagingDTO.java +++ /dev/null @@ -1,91 +0,0 @@ -package de.avatic.lcc.dto.report; - -import com.fasterxml.jackson.annotation.JsonProperty; -import de.avatic.lcc.model.utils.DimensionUnit; -import de.avatic.lcc.model.utils.WeightUnit; - -public class ReportPackagingDTO { - - private Double width; - - private Double height; - - private Double length; - - private Double weight; - - @JsonProperty("dimension_unit") - private DimensionUnit dimensionUnit; - - @JsonProperty("weight_unit") - private WeightUnit weightUnit; - - @JsonProperty("unit_count") - private Integer unitCount; - - private Integer layer; - - public Double getWidth() { - return width; - } - - public void setWidth(Double width) { - this.width = width; - } - - public Double getHeight() { - return height; - } - - public void setHeight(Double height) { - this.height = height; - } - - public Double getLength() { - return length; - } - - public void setLength(Double length) { - this.length = length; - } - - public Double getWeight() { - return weight; - } - - public void setWeight(Double weight) { - this.weight = weight; - } - - public DimensionUnit getDimensionUnit() { - return dimensionUnit; - } - - public void setDimensionUnit(DimensionUnit dimensionUnit) { - this.dimensionUnit = dimensionUnit; - } - - public WeightUnit getWeightUnit() { - return weightUnit; - } - - public void setWeightUnit(WeightUnit weightUnit) { - this.weightUnit = weightUnit; - } - - public Integer getUnitCount() { - return unitCount; - } - - public void setUnitCount(Integer unitCount) { - this.unitCount = unitCount; - } - - public Integer getLayer() { - return layer; - } - - public void setLayer(Integer layer) { - this.layer = layer; - } -} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportPremisesDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportPremisesDTO.java deleted file mode 100644 index 7a1b3a0..0000000 --- a/src/main/java/de/avatic/lcc/dto/report/ReportPremisesDTO.java +++ /dev/null @@ -1,70 +0,0 @@ -package de.avatic.lcc.dto.report; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; - -public class ReportPremisesDTO { - List quantities; - - @JsonProperty("hs_code") - private String hsCode; - - @JsonProperty("tariff_rate") - private Number tariffRate; - - private ReportContainerDTO container; - - private ReportPackagingDTO packaging; - - @JsonProperty("quota_share") - private ReportQuotaShareDTO quotaShare; - - public List getQuantities() { - return quantities; - } - - public void setQuantities(List quantities) { - this.quantities = quantities; - } - - public String getHsCode() { - return hsCode; - } - - public void setHsCode(String hsCode) { - this.hsCode = hsCode; - } - - public Number getTariffRate() { - return tariffRate; - } - - public void setTariffRate(Number tariffRate) { - this.tariffRate = tariffRate; - } - - public ReportContainerDTO getContainer() { - return container; - } - - public void setContainer(ReportContainerDTO container) { - this.container = container; - } - - public ReportPackagingDTO getPackaging() { - return packaging; - } - - public void setPackaging(ReportPackagingDTO packaging) { - this.packaging = packaging; - } - - public ReportQuotaShareDTO getQuotaShare() { - return quotaShare; - } - - public void setQuotaShare(ReportQuotaShareDTO quotaShare) { - this.quotaShare = quotaShare; - } -} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportQuantityDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportQuantityDTO.java deleted file mode 100644 index a8bfe7f..0000000 --- a/src/main/java/de/avatic/lcc/dto/report/ReportQuantityDTO.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.avatic.lcc.dto.report; - -import com.fasterxml.jackson.annotation.JsonProperty; -import de.avatic.lcc.dto.generic.NodeDTO; - -import java.util.List; - -public class ReportQuantityDTO { - - private NodeDTO destination; - private Number quantity; - - private List route; - - public NodeDTO getDestination() { - return destination; - } - - public void setDestination(NodeDTO destination) { - this.destination = destination; - } - - public Number getQuantity() { - return quantity; - } - - public void setQuantity(Number quantity) { - this.quantity = quantity; - } - - public List getRoute() { - return route; - } - - public void setRoute(List route) { - this.route = route; - } -} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportQuotaShareDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportQuotaShareDTO.java deleted file mode 100644 index d835568..0000000 --- a/src/main/java/de/avatic/lcc/dto/report/ReportQuotaShareDTO.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.avatic.lcc.dto.report; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class ReportQuotaShareDTO { - - @JsonProperty("oversea_share") - private Double overseaShare; - - @JsonProperty("air_freight_share") - private Double airFreightShare; - - @JsonProperty("transport_time") - private Double transportTime; - - @JsonProperty("safety_stock") - private Double safetyStock; - - - public Double getOverseaShare() { - return overseaShare; - } - - public void setOverseaShare(Double overseaShare) { - this.overseaShare = overseaShare; - } - - public Double getAirFreightShare() { - return airFreightShare; - } - - public void setAirFreightShare(Double airFreightShare) { - this.airFreightShare = airFreightShare; - } - - public Double getTransportTime() { - return transportTime; - } - - public void setTransportTime(Double transportTime) { - this.transportTime = transportTime; - } - - public Double getSafetyStock() { - return safetyStock; - } - - public void setSafetyStock(Double safetyStock) { - this.safetyStock = safetyStock; - } -} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportRouteEntryDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportRouteEntryDTO.java deleted file mode 100644 index 99245c1..0000000 --- a/src/main/java/de/avatic/lcc/dto/report/ReportRouteEntryDTO.java +++ /dev/null @@ -1,36 +0,0 @@ -package de.avatic.lcc.dto.report; - -import de.avatic.lcc.dto.generic.RouteType; - -public class ReportRouteEntryDTO { - - private String name; - private RouteType type; - - private ReportEntryDTO cost; - - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public RouteType getType() { - return type; - } - - public void setType(RouteType type) { - this.type = type; - } - - public ReportEntryDTO getCost() { - return cost; - } - - public void setCost(ReportEntryDTO cost) { - this.cost = cost; - } -} diff --git a/src/main/java/de/avatic/lcc/dto/report/ReportSectionDTO.java b/src/main/java/de/avatic/lcc/dto/report/ReportSectionDTO.java new file mode 100644 index 0000000..50f6e5d --- /dev/null +++ b/src/main/java/de/avatic/lcc/dto/report/ReportSectionDTO.java @@ -0,0 +1,74 @@ +package de.avatic.lcc.dto.report; + +import com.fasterxml.jackson.annotation.JsonProperty; +import de.avatic.lcc.dto.generic.NodeDTO; +import de.avatic.lcc.dto.generic.RateType; +import de.avatic.lcc.dto.generic.TransportType; + +public class ReportSectionDTO { + + private Integer id; + + @JsonProperty("route_type") + private TransportType transportType; + + @JsonProperty("rate_type") + private RateType rateType; + + @JsonProperty("from_node") + private NodeDTO fromNode; + + @JsonProperty("cost") + private ReportEntryDTO cost; + + @JsonProperty("duration") + private ReportEntryDTO duration; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public TransportType getTransportType() { + return transportType; + } + + public void setTransportType(TransportType transportType) { + this.transportType = transportType; + } + + public RateType getRateType() { + return rateType; + } + + public void setRateType(RateType rateType) { + this.rateType = rateType; + } + + public NodeDTO getFromNode() { + return fromNode; + } + + public void setFromNode(NodeDTO fromNode) { + this.fromNode = fromNode; + } + + public ReportEntryDTO getCost() { + return cost; + } + + public void setCost(ReportEntryDTO cost) { + this.cost = cost; + } + + public ReportEntryDTO getDuration() { + return duration; + } + + public void setDuration(ReportEntryDTO duration) { + this.duration = duration; + } +} diff --git a/src/main/java/de/avatic/lcc/model/calculations/CalculationJobRouteSection.java b/src/main/java/de/avatic/lcc/model/calculations/CalculationJobRouteSection.java index 633cd1f..3399d6c 100644 --- a/src/main/java/de/avatic/lcc/model/calculations/CalculationJobRouteSection.java +++ b/src/main/java/de/avatic/lcc/model/calculations/CalculationJobRouteSection.java @@ -1,12 +1,16 @@ package de.avatic.lcc.model.calculations; + import de.avatic.lcc.dto.generic.RateType; + import de.avatic.lcc.dto.generic.TransportType; + import java.math.BigDecimal; public class CalculationJobRouteSection { private Integer id; private Integer premiseRouteSectionId; private Integer calculationJobDestinationId; - private CalculationJobTransportationRuleType usedRule; + private TransportType transportType; + private RateType rateType; private Boolean isUnmixedPrice; private Boolean isCbmPrice; private Boolean isWeightPrice; @@ -21,6 +25,23 @@ private BigDecimal annualCost; private Integer transitTime; + + public RateType getRateType() { + return rateType; + } + + public void setRateType(RateType rateType) { + this.rateType = rateType; + } + + public TransportType getTransportType() { + return transportType; + } + + public void setTransportType(TransportType transportType) { + this.transportType = transportType; + } + public Integer getId() { return id; } @@ -45,14 +66,6 @@ this.calculationJobDestinationId = calculationJobDestinationId; } - public CalculationJobTransportationRuleType getUsedRule() { - return usedRule; - } - - public void setUsedRule(CalculationJobTransportationRuleType usedRule) { - this.usedRule = usedRule; - } - public Boolean getUnmixedPrice() { return isUnmixedPrice; } diff --git a/src/main/java/de/avatic/lcc/model/premises/route/Destination.java b/src/main/java/de/avatic/lcc/model/premises/route/Destination.java index 996faeb..d267f5e 100644 --- a/src/main/java/de/avatic/lcc/model/premises/route/Destination.java +++ b/src/main/java/de/avatic/lcc/model/premises/route/Destination.java @@ -23,6 +23,26 @@ public class Destination { private BigDecimal disposalCost; + private BigDecimal geoLat; + + private BigDecimal geoLng; + + public BigDecimal getGeoLat() { + return geoLat; + } + + public void setGeoLat(BigDecimal geoLat) { + this.geoLat = geoLat; + } + + public BigDecimal getGeoLng() { + return geoLng; + } + + public void setGeoLng(BigDecimal geoLng) { + this.geoLng = geoLng; + } + public Integer getId() { return id; } diff --git a/src/main/java/de/avatic/lcc/model/premises/route/RouteSection.java b/src/main/java/de/avatic/lcc/model/premises/route/RouteSection.java index ad182af..ed65946 100644 --- a/src/main/java/de/avatic/lcc/model/premises/route/RouteSection.java +++ b/src/main/java/de/avatic/lcc/model/premises/route/RouteSection.java @@ -1,6 +1,7 @@ package de.avatic.lcc.model.premises.route; -import de.avatic.lcc.dto.generic.RouteType; +import de.avatic.lcc.dto.generic.RateType; +import de.avatic.lcc.dto.generic.TransportType; public class RouteSection { @@ -10,7 +11,9 @@ public class RouteSection { private Integer listPosition; - private RouteType transportType; + private TransportType transportType; + + private RateType rateType; private Boolean isPreRun; @@ -24,6 +27,13 @@ public class RouteSection { private Integer toRouteNodeId; + public RateType getRateType() { + return rateType; + } + + public void setRateType(RateType rateType) { + this.rateType = rateType; + } public Integer getId() { return id; @@ -49,11 +59,11 @@ public class RouteSection { this.listPosition = listPosition; } - public RouteType getTransportType() { + public TransportType getTransportType() { return transportType; } - public void setTransportType(RouteType transportType) { + public void setTransportType(TransportType transportType) { this.transportType = transportType; } diff --git a/src/main/java/de/avatic/lcc/model/premises/route/RouteSectionType.java b/src/main/java/de/avatic/lcc/model/premises/route/RouteSectionType.java index b71a821..ad3c92f 100644 --- a/src/main/java/de/avatic/lcc/model/premises/route/RouteSectionType.java +++ b/src/main/java/de/avatic/lcc/model/premises/route/RouteSectionType.java @@ -1,5 +1,5 @@ package de.avatic.lcc.model.premises.route; public enum RouteSectionType { - RAIL, SEA, POST_RUN, ROAD, D2D + RAIL, SEA, POST_RUN, ROAD, MATRIX } diff --git a/src/main/java/de/avatic/lcc/repositories/calculation/CalculationJobRouteSectionRepository.java b/src/main/java/de/avatic/lcc/repositories/calculation/CalculationJobRouteSectionRepository.java index f8a752b..83c01af 100644 --- a/src/main/java/de/avatic/lcc/repositories/calculation/CalculationJobRouteSectionRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/calculation/CalculationJobRouteSectionRepository.java @@ -1,7 +1,7 @@ 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.calculations.CalculationJobTransportationRuleType; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; @@ -63,7 +63,7 @@ public class CalculationJobRouteSectionRepository { entity.setCalculationJobDestinationId(rs.getInt("calculation_job_destination_id")); // Rule and price type flags - entity.setUsedRule(CalculationJobTransportationRuleType.valueOf(rs.getString("used_rule"))); + entity.setTransportType(TransportType.valueOf(rs.getString("transport_type"))); entity.setUnmixedPrice(rs.getBoolean("is_unmixed_price")); entity.setCbmPrice(rs.getBoolean("is_cbm_price")); entity.setWeightPrice(rs.getBoolean("is_weight_price")); diff --git a/src/main/java/de/avatic/lcc/repositories/premise/DestinationRepository.java b/src/main/java/de/avatic/lcc/repositories/premise/DestinationRepository.java index 40bb6b7..3521cc7 100644 --- a/src/main/java/de/avatic/lcc/repositories/premise/DestinationRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/premise/DestinationRepository.java @@ -120,6 +120,8 @@ public class DestinationRepository { entity.setRepackingCost(rs.getBigDecimal("repacking_cost")); entity.setHandlingCost(rs.getBigDecimal("handling_cost")); entity.setDisposalCost(rs.getBigDecimal("disposal_cost")); + entity.setGeoLat(rs.getBigDecimal("geo_lat")); + entity.setGeoLng(rs.getBigDecimal("geo_lng")); return entity; } diff --git a/src/main/java/de/avatic/lcc/repositories/premise/RouteNodeRepository.java b/src/main/java/de/avatic/lcc/repositories/premise/RouteNodeRepository.java index c690b5f..68f87f1 100644 --- a/src/main/java/de/avatic/lcc/repositories/premise/RouteNodeRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/premise/RouteNodeRepository.java @@ -70,6 +70,28 @@ public class RouteNodeRepository { return keyHolder.getKey() != null ? keyHolder.getKey().intValue() : null; } + public Optional getFromNodeBySectionId(Integer id) { + String sql = "SELECT * FROM premise_route_section LEFT JOIN premise_route_node ON premise_route_node.id = premise_route_section.from_route_node_id WHERE premise_route_section.id = ?"; + + var node = jdbcTemplate.query(sql, new RouteNodeMapper(), id); + + if(node.isEmpty()) + return Optional.empty(); + + return Optional.of(node.getFirst()); + } + + public Optional getToNodeBySectionId(Integer id) { + String sql = "SELECT * FROM premise_route_section LEFT JOIN premise_route_node ON premise_route_node.id = premise_route_section.to_route_node_id WHERE premise_route_section.id = ?"; + + var node = jdbcTemplate.query(sql, new RouteNodeMapper(), id); + + if(node.isEmpty()) + return Optional.empty(); + + return Optional.of(node.getFirst()); + } + private static class RouteNodeMapper implements RowMapper { @Override diff --git a/src/main/java/de/avatic/lcc/repositories/premise/RouteSectionRepository.java b/src/main/java/de/avatic/lcc/repositories/premise/RouteSectionRepository.java index 4127a00..2cc36f7 100644 --- a/src/main/java/de/avatic/lcc/repositories/premise/RouteSectionRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/premise/RouteSectionRepository.java @@ -1,6 +1,7 @@ package de.avatic.lcc.repositories.premise; -import de.avatic.lcc.dto.generic.RouteType; +import de.avatic.lcc.dto.generic.RateType; +import de.avatic.lcc.dto.generic.TransportType; import de.avatic.lcc.model.premises.route.RouteSection; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @@ -44,8 +45,8 @@ public class RouteSectionRepository { } public Integer insert(RouteSection premiseRouteSection) { - String sql = "INSERT INTO premise_route_section (premise_route_id, from_route_node_id, to_route_node_id, list_position, transport_type, is_pre_run, is_main_run, is_post_run, is_outdated) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + String sql = "INSERT INTO premise_route_section (premise_route_id, from_route_node_id, to_route_node_id, list_position, transport_type, rate_type, is_pre_run, is_main_run, is_post_run, is_outdated) " + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; KeyHolder keyHolder = new GeneratedKeyHolder(); jdbcTemplate.update(connection -> { @@ -55,10 +56,11 @@ public class RouteSectionRepository { ps.setInt(3, premiseRouteSection.getToRouteNodeId()); ps.setInt(4, premiseRouteSection.getListPosition()); ps.setString(5, premiseRouteSection.getTransportType().name()); - ps.setBoolean(6, premiseRouteSection.getPreRun()); - ps.setBoolean(7, premiseRouteSection.getMainRun()); - ps.setBoolean(8, premiseRouteSection.getPostRun()); - ps.setBoolean(9, premiseRouteSection.getOutdated()); + ps.setString(6, premiseRouteSection.getRateType().name()); + ps.setBoolean(7, premiseRouteSection.getPreRun()); + ps.setBoolean(8, premiseRouteSection.getMainRun()); + ps.setBoolean(9, premiseRouteSection.getPostRun()); + ps.setBoolean(10, premiseRouteSection.getOutdated()); return ps; }, keyHolder); @@ -82,7 +84,8 @@ public class RouteSectionRepository { entity.setToRouteNodeId(rs.getInt("to_route_node_id")); entity.setListPosition(rs.getInt("list_position")); - entity.setTransportType(RouteType.valueOf(rs.getString("transport_type"))); + entity.setTransportType(TransportType.valueOf(rs.getString("transport_type"))); + entity.setRateType(RateType.valueOf(rs.getString("rate_type"))); entity.setPreRun(rs.getBoolean("is_pre_run")); entity.setMainRun(rs.getBoolean("is_main_run")); diff --git a/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java b/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java index b4d4f79..221d346 100644 --- a/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java +++ b/src/main/java/de/avatic/lcc/repositories/users/UserNodeRepository.java @@ -61,7 +61,7 @@ public class UserNodeRepository { AND p.user_supplier_node_id IS NOT NULL """; - return jdbcTemplate.query(userSuppliersSql, new NodeMapper(), materialId, periodId)); + return jdbcTemplate.query(userSuppliersSql, new NodeMapper(), materialId, periodId); } diff --git a/src/main/java/de/avatic/lcc/service/access/ContainerRateService.java b/src/main/java/de/avatic/lcc/service/access/ContainerRateService.java index b6235a3..a0e188b 100644 --- a/src/main/java/de/avatic/lcc/service/access/ContainerRateService.java +++ b/src/main/java/de/avatic/lcc/service/access/ContainerRateService.java @@ -2,7 +2,7 @@ package de.avatic.lcc.service.access; import de.avatic.lcc.dto.configuration.rates.ContainerRateDTO; import de.avatic.lcc.dto.generic.ContainerType; -import de.avatic.lcc.dto.generic.RouteType; +import de.avatic.lcc.dto.generic.TransportType; import de.avatic.lcc.model.rates.ContainerRate; import de.avatic.lcc.repositories.NodeRepository; import de.avatic.lcc.repositories.pagination.SearchQueryPagination; @@ -106,7 +106,7 @@ public class ContainerRateService { dto.setId(entity.getId()); dto.setLeadTime(entity.getLeadTime()); - dto.setType(RouteType.valueOf(entity.getType().name())); + dto.setType(TransportType.valueOf(entity.getType().name())); dto.setValidityPeriod(validityPeriodTransformer.toValidityPeriodDTO(validityPeriodRepository.getById(entity.getValidityPeriodId()))); dto.setLeadTime(entity.getLeadTime()); dto.setOrigin(nodeTransformer.toNodeDTO(nodeRepository.getById(entity.getFromNodeId()).orElseThrow())); diff --git a/src/main/java/de/avatic/lcc/service/access/DestinationService.java b/src/main/java/de/avatic/lcc/service/access/DestinationService.java index 513d84c..b662d08 100644 --- a/src/main/java/de/avatic/lcc/service/access/DestinationService.java +++ b/src/main/java/de/avatic/lcc/service/access/DestinationService.java @@ -76,6 +76,8 @@ public class DestinationService { destination.setRepackingCost(null); destination.setRateD2d(BigDecimal.ZERO); destination.setId(destinationRepository.insert(destination)); + destination.setGeoLat(destinationNode.getGeoLat()); + destination.setGeoLng(destinationNode.getGeoLng()); Node source = premise.getSupplierNodeId() == null ? userNodeRepository.getById(premise.getUserSupplierNodeId()).orElseThrow() : nodeRepository.getById(premise.getSupplierNodeId()).orElseThrow(); findRouteAndSave(destination.getId(), destinationNode, source, premise.getSupplierNodeId() == null); diff --git a/src/main/java/de/avatic/lcc/service/bulk/BulkExportService.java b/src/main/java/de/avatic/lcc/service/bulk/BulkExportService.java index e29ee98..a787814 100644 --- a/src/main/java/de/avatic/lcc/service/bulk/BulkExportService.java +++ b/src/main/java/de/avatic/lcc/service/bulk/BulkExportService.java @@ -12,9 +12,14 @@ import org.apache.poi.ss.usermodel.SheetVisibility; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.InputStreamSource; import org.springframework.stereotype.Service; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + @Service public class BulkExportService { @@ -42,54 +47,56 @@ public class BulkExportService { this.sheetPassword = sheetPassword; } - public InputStreamSource generateExport(BulkFileType bulkFileType) { + public InputStreamSource generateExport(BulkFileType bulkFileType) throws IOException { return generateExport(bulkFileType, validityPeriodRepository.getValidPeriodId()); } - public InputStreamSource generateExport(BulkFileType bulkFileType, Integer periodId) { - Workbook workbook = new XSSFWorkbook(); - Sheet worksheet = workbook.createSheet(BulkFileTypes.valueOf(bulkFileType.name()).getSheetName()); + public InputStreamSource generateExport(BulkFileType bulkFileType, Integer periodId) throws IOException { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + Workbook workbook = new XSSFWorkbook(); + Sheet worksheet = workbook.createSheet(BulkFileTypes.valueOf(bulkFileType.name()).getSheetName()); - CellStyle style = headerCellStyleProvider.createHeaderCellStyle(workbook); + CellStyle style = headerCellStyleProvider.createHeaderCellStyle(workbook); - //TODO: check if a parallel task is needed. + //TODO: check if a parallel task is needed. + if (bulkFileType.equals(BulkFileType.COUNTRY_MATRIX) || bulkFileType.equals(BulkFileType.NODE)) { + var hiddenCountrySheet = workbook.createSheet(HiddenTableType.COUNTRY_HIDDEN_TABLE.getSheetName()); + hiddenCountryExcelMapper.fillSheet(hiddenCountrySheet, style); + hiddenCountrySheet.protectSheet(sheetPassword); + workbook.setSheetVisibility(workbook.getSheetIndex(hiddenCountrySheet), SheetVisibility.VERY_HIDDEN); + } else if (bulkFileType.equals(BulkFileType.CONTAINER_RATE) || bulkFileType.equals(BulkFileType.PACKAGING)) { + var hiddenNodeSheet = workbook.createSheet(HiddenTableType.NODE_HIDDEN_TABLE.getSheetName()); + hiddenNodeExcelMapper.fillSheet(hiddenNodeSheet, style, BulkFileType.PACKAGING.equals(bulkFileType)); + hiddenNodeSheet.protectSheet(sheetPassword); + workbook.setSheetVisibility(workbook.getSheetIndex(hiddenNodeSheet), SheetVisibility.VERY_HIDDEN); + } - if(bulkFileType.equals(BulkFileType.COUNTRY_MATRIX) || bulkFileType.equals(BulkFileType.NODE)) - { - var hiddenCountrySheet = workbook.createSheet(HiddenTableType.COUNTRY_HIDDEN_TABLE.getSheetName()); - hiddenCountryExcelMapper.fillSheet(hiddenCountrySheet, style); - hiddenCountrySheet.protectSheet(sheetPassword); - workbook.setSheetVisibility(workbook.getSheetIndex(hiddenCountrySheet), SheetVisibility.VERY_HIDDEN); + // Create headers based on the bulk file type + switch (bulkFileType) { + case CONTAINER_RATE: + containerRateExcelMapper.fillSheet(worksheet, style, periodId); + break; + case COUNTRY_MATRIX: + matrixRateExcelMapper.fillSheet(worksheet, style, periodId); + break; + case MATERIAL: + materialExcelMapper.fillSheet(worksheet, style); + break; + case PACKAGING: + packagingExcelMapper.fillSheet(worksheet, style); + break; + case NODE: + nodeExcelMapper.fillSheet(worksheet, style); + break; + } + + // Return the Excel file as an InputStreamSource + workbook.write(outputStream); + return new ByteArrayResource(outputStream.toByteArray()); + } catch (IOException e) { + throw new RuntimeException("Failed to generate template", e); } - else if(bulkFileType.equals(BulkFileType.CONTAINER_RATE) || bulkFileType.equals(BulkFileType.PACKAGING)) - { - var hiddenNodeSheet = workbook.createSheet(HiddenTableType.NODE_HIDDEN_TABLE.getSheetName()); - hiddenNodeExcelMapper.fillSheet(hiddenNodeSheet, style, BulkFileType.PACKAGING.equals(bulkFileType)); - hiddenNodeSheet.protectSheet(sheetPassword); - workbook.setSheetVisibility(workbook.getSheetIndex(hiddenNodeSheet), SheetVisibility.VERY_HIDDEN); - } - - // Create headers based on the bulk file type - switch (bulkFileType) { - case CONTAINER_RATE: - containerRateExcelMapper.fillSheet(worksheet, style, periodId); - break; - case COUNTRY_MATRIX: - matrixRateExcelMapper.fillSheet(worksheet, style, periodId); - break; - case MATERIAL: - materialExcelMapper.fillSheet(worksheet, style); - break; - case PACKAGING: - packagingExcelMapper.fillSheet(worksheet, style); - break; - case NODE: - nodeExcelMapper.fillSheet(worksheet, style); - break; - } - - return null; } } diff --git a/src/main/java/de/avatic/lcc/service/bulk/TemplateExportService.java b/src/main/java/de/avatic/lcc/service/bulk/TemplateExportService.java index 2e5b2bc..d329592 100644 --- a/src/main/java/de/avatic/lcc/service/bulk/TemplateExportService.java +++ b/src/main/java/de/avatic/lcc/service/bulk/TemplateExportService.java @@ -93,6 +93,7 @@ public class TemplateExportService { } // Return the Excel file as an InputStreamSource + workbook.write(outputStream); return new ByteArrayResource(outputStream.toByteArray()); } catch (IOException e) { throw new RuntimeException("Failed to generate template", e); diff --git a/src/main/java/de/avatic/lcc/service/calculation/RoutingService.java b/src/main/java/de/avatic/lcc/service/calculation/RoutingService.java index 796d2a1..a6d99ef 100644 --- a/src/main/java/de/avatic/lcc/service/calculation/RoutingService.java +++ b/src/main/java/de/avatic/lcc/service/calculation/RoutingService.java @@ -1,6 +1,7 @@ package de.avatic.lcc.service.calculation; -import de.avatic.lcc.dto.generic.RouteType; +import de.avatic.lcc.dto.generic.RateType; +import de.avatic.lcc.dto.generic.TransportType; import de.avatic.lcc.model.nodes.Node; import de.avatic.lcc.model.premises.route.*; import de.avatic.lcc.model.properties.SystemPropertyMappingId; @@ -182,6 +183,7 @@ public class RoutingService { RouteSection routeSection = new RouteSection(); routeSection.setTransportType(mapRouteType(section)); + routeSection.setRateType(mapRateType(section)); routeSection.setFromRouteNodeId(section.getFromNode().getId()); routeSection.setToRouteNodeId(section.getToNode().getId()); routeSection.setMainRun(section.getType().equals(TemporaryRateObject.TemporaryRateObjectType.MAIN_RUN)); @@ -194,17 +196,25 @@ public class RoutingService { } - private RouteType mapRouteType(TemporaryRateObject rate) { + private RateType mapRateType(TemporaryRateObject rate) { + + if (Objects.requireNonNull(rate.getType()) == TemporaryRateObject.TemporaryRateObjectType.MATRIX) { + return RateType.MATRIX; + } + return RateType.CONTAINER; + } + + private TransportType mapRouteType(TemporaryRateObject rate) { switch(rate.getType()) { - case MATRIX, CONTAINER -> { - return RouteType.ROAD; + case CONTAINER, MATRIX -> { + return TransportType.ROAD; } case POST_RUN -> { - return RouteType.POST_RUN; + return TransportType.POST_RUN; } case MAIN_RUN -> { - return RouteType.valueOf(rate.getContainerRateTye().name()); + return TransportType.valueOf(rate.getContainerRateTye().name()); } } diff --git a/src/main/java/de/avatic/lcc/service/report/ExcelReportingService.java b/src/main/java/de/avatic/lcc/service/report/ExcelReportingService.java index 455b624..3ce3ff9 100644 --- a/src/main/java/de/avatic/lcc/service/report/ExcelReportingService.java +++ b/src/main/java/de/avatic/lcc/service/report/ExcelReportingService.java @@ -1,17 +1,184 @@ package de.avatic.lcc.service.report; +import de.avatic.lcc.dto.generic.NodeDTO; +import de.avatic.lcc.dto.report.ReportDTO; +import de.avatic.lcc.dto.report.ReportDestinationDTO; +import de.avatic.lcc.dto.report.ReportEntryDTO; +import de.avatic.lcc.service.bulk.helper.HeaderCellStyleProvider; +import de.avatic.lcc.service.bulk.helper.HeaderGenerator; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.core.io.ByteArrayResource; import org.springframework.stereotype.Service; -import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; @Service public class ExcelReportingService { - public ByteArrayInputStream generateExcelReport(Integer materialId, List nodeIds) { + private final ReportingService reportingService; + private final HeaderCellStyleProvider headerCellStyleProvider; + private final HeaderGenerator headerGenerator; - return null; + public ExcelReportingService(ReportingService reportingService, HeaderCellStyleProvider headerCellStyleProvider, HeaderGenerator headerGenerator) { + + this.reportingService = reportingService; + this.headerCellStyleProvider = headerCellStyleProvider; + this.headerGenerator = headerGenerator; + } + + public ByteArrayResource generateExcelReport(Integer materialId, List nodeIds) { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { + var reports = reportingService.getReport(materialId, nodeIds); + + Workbook workbook = new XSSFWorkbook(); + Sheet sheet = workbook.createSheet("report"); + + CellStyle headerStyle = headerCellStyleProvider.createHeaderCellStyle(workbook); + headerGenerator.generateHeader(sheet, reports.stream().map(ReportDTO::getSupplier).map(NodeDTO::getName).toArray(String[]::new), headerStyle); + + List flatteners = reports.stream().map(ReportFlattener::new).toList(); + + int rowIdx = 1; + while(true) { + boolean hasData = false; + + var row = sheet.createRow(rowIdx); + int cellIdx = 0; + for(ReportFlattener flattener : flatteners) { + if(cellIdx == 0) { + row.createCell(cellIdx++).setCellValue(flattener.getHeader(rowIdx)); + hasData = true; + } + row.createCell(cellIdx++).setCellValue(flattener.getCell(rowIdx)); + } + + rowIdx++; + if(!hasData) break; + } + + // Return the Excel file as an InputStreamSource + workbook.write(outputStream); + return new ByteArrayResource(outputStream.toByteArray()); + } catch ( + IOException e) { + throw new RuntimeException("Failed to generate template", e); + } + } + + private void mapToCell(Sheet sheet, ReportDTO reportDTO, Cell cell, int rowIdx) { + + + } + + private static class ReportFlattener { + + private static final String SUPPLIER_NAME = "Supplier"; + private static final String SUPPLIER_ADDRESS = "Address"; + + private static final String DESTINATION_NAME = "Destination"; + private static final String DESTINATION_ADDRESS = "Address"; + + private static final String DESTINATION_QUANTITY = "Annual quantity"; + private static final String DESTINATION_HS_CODE = "HS code"; + private static final String DESTINATION_TARIFF_RATE = "Tariff rate"; + private static final String DESTINATION_OVERSHARE = "Oversea share"; + private static final String DESTINATION_AIR_FREIGHT_SHARE = "Air freight share"; + private static final String DESTINATION_TRANSPORT_TIME = "Transport time"; + private static final String DESTINATION_SAFETY_STOCK = "Safety stock"; + + private static final String DESTINATION_WIDTH = "HU Width"; + private static final String DESTINATION_HEIGHT = "HU Height"; + private static final String DESTINATION_LENGTH = "HU Length"; + private static final String DESTINATION_WEIGHT = "HU Weight"; + private static final String DESTINATION_HU_UNIT_COUNT = "HU Unit count"; + + private static final String DESTINATION_WEIGHT_UNIT = "HU Weight unit"; + private static final String DESTINATION_DIMENSION_UNIT = "HU Unit"; + + private static final String DESTINATION_CONTAINER_LAYER = "Container layers"; + private static final String DESTINATION_CONTAINER_UNIT_COUNT = "Container unit count"; + private static final String DESTINATION_CONTAINER_UTILIZATION = "Container utilization"; + private static final String DESTINATION_CONTAINER_TYPE = "Container type"; + private static final String DESTINATION_CONTAINER_WEIGHT_EXCEEDED = "Container weight exceeded"; + private static final String DESTINATION_CONTAINER_RATE = "Container rate"; + private static final String DESTINATION_MIXED = "Mixed"; + + + private final ReportDTO report; + private List data = new ArrayList<>(); + private List dataHeader = new ArrayList<>(); + + public ReportFlattener(ReportDTO report) { + this.report = report; + flatten(); + } + + private void flatten() { + + addData(SUPPLIER_NAME, report.getSupplier().getName()); + addData(SUPPLIER_ADDRESS, report.getSupplier().getAddress()); + + report.getCost().keySet().forEach(costName -> addData(costName, report.getCost().get(costName))); + report.getRisk().keySet().forEach(riskName -> addData(riskName, report.getRisk().get(riskName))); + + report.getDestinations().forEach(this::flattenDestination); + } + + private void flattenDestination(ReportDestinationDTO destination) { + addData(DESTINATION_NAME, destination.getDestination().getName()); + addData(DESTINATION_ADDRESS, destination.getDestination().getAddress()); + + addData(DESTINATION_QUANTITY, destination.getAnnualQuantity().toString()); + addData(DESTINATION_HS_CODE, destination.getHsCode()); + addData(DESTINATION_TARIFF_RATE, destination.getTariffRate().toString()); + addData(DESTINATION_OVERSHARE, destination.getOverseaShare().toString()); + addData(DESTINATION_AIR_FREIGHT_SHARE, destination.getAirFreightShare().toString()); + addData(DESTINATION_TRANSPORT_TIME, destination.getTransportTime().toString()); + addData(DESTINATION_SAFETY_STOCK, destination.getSafetyStock().toString()); + + addData(DESTINATION_WIDTH, destination.getWidth().toString()); + addData(DESTINATION_HEIGHT, destination.getHeight().toString()); + addData(DESTINATION_LENGTH, destination.getLength().toString()); + addData(DESTINATION_DIMENSION_UNIT, destination.getDimensionUnit().toString()); + addData(DESTINATION_WEIGHT, destination.getWeight().toString()); + addData(DESTINATION_WEIGHT_UNIT, destination.getWeightUnit().toString()); + addData(DESTINATION_HU_UNIT_COUNT, destination.getHuUnitCount().toString()); + addData(DESTINATION_CONTAINER_LAYER, destination.getLayer().toString()); + + addData(DESTINATION_CONTAINER_UNIT_COUNT, destination.getUnitCount().toString()); + addData(DESTINATION_CONTAINER_UTILIZATION, destination.getUtilization().toString()); + addData(DESTINATION_CONTAINER_TYPE, destination.getType().toString()); + addData(DESTINATION_CONTAINER_WEIGHT_EXCEEDED, destination.getWeightExceeded().toString()); + addData(DESTINATION_CONTAINER_RATE, destination.getRate().toString()); + addData(DESTINATION_MIXED, destination.getMixed().toString()); + + } + + private void addData(String header, String data) { + this.dataHeader.add(header); + this.data.add(data); + } + + private void addData(String header, ReportEntryDTO data) { + this.dataHeader.add(header); + this.data.add(data.getTotal() + " (" + data.getPercentage().doubleValue()*100 + "%)"); + } + + public String getCell(int rowIdx) { + return data.get(rowIdx); + } + + public String getHeader(int rowIdx) { + return dataHeader.get(rowIdx); + } } } diff --git a/src/main/java/de/avatic/lcc/service/report/ReportingService.java b/src/main/java/de/avatic/lcc/service/report/ReportingService.java index 6fd9212..245cece 100644 --- a/src/main/java/de/avatic/lcc/service/report/ReportingService.java +++ b/src/main/java/de/avatic/lcc/service/report/ReportingService.java @@ -2,12 +2,8 @@ package de.avatic.lcc.service.report; import de.avatic.lcc.dto.generic.NodeDTO; import de.avatic.lcc.dto.report.ReportDTO; -import de.avatic.lcc.model.calculations.CalculationJobDestination; -import de.avatic.lcc.model.calculations.CalculationJobRouteSection; import de.avatic.lcc.repositories.NodeRepository; -import de.avatic.lcc.repositories.calculation.CalculationJobDestinationRepository; import de.avatic.lcc.repositories.calculation.CalculationJobRepository; -import de.avatic.lcc.repositories.calculation.CalculationJobRouteSectionRepository; import de.avatic.lcc.repositories.rates.ValidityPeriodRepository; import de.avatic.lcc.repositories.users.UserNodeRepository; import de.avatic.lcc.service.transformer.generic.NodeTransformer; @@ -16,7 +12,6 @@ import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Optional; @Service @@ -63,7 +58,6 @@ public class ReportingService { var periodId = period.get().getId(); var jobs = nodeIds.stream().map(nodeId -> calculationJobRepository.getCalculationJob(periodId, nodeId,materialId)).filter(Optional::isPresent).map(Optional::get).toList(); - return jobs.stream().map(reportTransformer::toReportDTO).toList(); } diff --git a/src/main/java/de/avatic/lcc/service/transformer/premise/RouteSectionTransformer.java b/src/main/java/de/avatic/lcc/service/transformer/premise/RouteSectionTransformer.java deleted file mode 100644 index ed390e5..0000000 --- a/src/main/java/de/avatic/lcc/service/transformer/premise/RouteSectionTransformer.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.avatic.lcc.service.transformer.premise; - -import org.springframework.stereotype.Service; - -@Service -public class RouteSectionTransformer { - - public RouteSectionDTO - -} diff --git a/src/main/java/de/avatic/lcc/service/transformer/premise/RouteTransformer.java b/src/main/java/de/avatic/lcc/service/transformer/premise/RouteTransformer.java index e1b2181..70a3aab 100644 --- a/src/main/java/de/avatic/lcc/service/transformer/premise/RouteTransformer.java +++ b/src/main/java/de/avatic/lcc/service/transformer/premise/RouteTransformer.java @@ -1,8 +1,7 @@ package de.avatic.lcc.service.transformer.premise; import de.avatic.lcc.dto.calculation.RouteDTO; -import de.avatic.lcc.dto.calculation.TransitNodeDTO; -import de.avatic.lcc.dto.generic.RouteType; +import de.avatic.lcc.dto.generic.TransportType; import de.avatic.lcc.model.premises.route.RouteNode; import de.avatic.lcc.model.premises.route.RouteSection; import de.avatic.lcc.repositories.premise.RouteNodeRepository; @@ -39,7 +38,7 @@ public class RouteTransformer { List sections = routeSectionRepository.getByRouteId(entity.getId()); dto.setTransitNodes(getRouteNodes(sections).stream().map(nodeTransformer::toNodeDTO).toList()); - dto.setType(RouteType.valueOf(sections.stream().filter(RouteSection::getMainRun).findFirst().orElseThrow().getTransportType().name())); + dto.setType(TransportType.valueOf(sections.stream().filter(RouteSection::getMainRun).findFirst().orElseThrow().getTransportType().name())); return dto; } diff --git a/src/main/java/de/avatic/lcc/service/transformer/report/ReportTransformer.java b/src/main/java/de/avatic/lcc/service/transformer/report/ReportTransformer.java index f17310f..ff65656 100644 --- a/src/main/java/de/avatic/lcc/service/transformer/report/ReportTransformer.java +++ b/src/main/java/de/avatic/lcc/service/transformer/report/ReportTransformer.java @@ -1,7 +1,12 @@ package de.avatic.lcc.service.transformer.report; import de.avatic.lcc.dto.generic.ContainerType; -import de.avatic.lcc.dto.report.*; +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; +import de.avatic.lcc.dto.report.ReportEntryDTO; +import de.avatic.lcc.dto.report.ReportSectionDTO; import de.avatic.lcc.model.calculations.CalculationJob; import de.avatic.lcc.model.calculations.CalculationJobDestination; import de.avatic.lcc.model.calculations.CalculationJobRouteSection; @@ -11,6 +16,7 @@ import de.avatic.lcc.repositories.calculation.CalculationJobDestinationRepositor 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; @@ -27,19 +33,17 @@ public class ReportTransformer { private final CalculationJobDestinationRepository calculationJobDestinationRepository; private final CalculationJobRouteSectionRepository calculationJobRouteSectionRepository; private final PremiseRepository premiseRepository; - private final DestinationRepository destinationRepository; private final NodeRepository nodeRepository; - private final RouteSectionRepository routeSectionRepository; private final NodeTransformer nodeTransformer; + private final RouteNodeRepository routeNodeRepository; - public ReportTransformer(CalculationJobDestinationRepository calculationJobDestinationRepository, CalculationJobRouteSectionRepository calculationJobRouteSectionRepository, PremiseRepository premiseRepository, DestinationRepository destinationRepository, NodeRepository nodeRepository, RouteSectionRepository routeSectionRepository, NodeTransformer nodeTransformer) { + public ReportTransformer(CalculationJobDestinationRepository calculationJobDestinationRepository, CalculationJobRouteSectionRepository calculationJobRouteSectionRepository, PremiseRepository premiseRepository, NodeRepository nodeRepository, NodeTransformer nodeTransformer, RouteNodeRepository routeNodeRepository) { this.calculationJobDestinationRepository = calculationJobDestinationRepository; this.calculationJobRouteSectionRepository = calculationJobRouteSectionRepository; this.premiseRepository = premiseRepository; - this.destinationRepository = destinationRepository; this.nodeRepository = nodeRepository; - this.routeSectionRepository = routeSectionRepository; this.nodeTransformer = nodeTransformer; + this.routeNodeRepository = routeNodeRepository; } public ReportDTO toReportDTO(CalculationJob job) { @@ -53,98 +57,84 @@ public class ReportTransformer { reportDTO.setCost(getCostMap(job, destinations)); reportDTO.setRisk(getRisk(job, destinations)); + reportDTO.setDestination(destinations.stream().map(d -> getDestinationDTO(d, sections.get(d.getId()), premise)).toList()); - ReportPremisesDTO premisesDTO = new ReportPremisesDTO(); - premisesDTO.setQuantities(destinations.stream().map(q -> getQuantitiesDTO(q, sections.get(q.getId()))).toList()); - - premisesDTO.setContainer(getContainerDTO(destinations, sections, premise)); - premisesDTO.setPackaging(getPackagingDTO(destinations, premise)); - premisesDTO.setQuotaShare(getQuotaShare(destinations, sections, premise)); - premisesDTO.setHsCode(premise.getHsCode()); - - reportDTO.setPremises(premisesDTO); + if(!reportDTO.getDestinations().isEmpty()) { + var source = reportDTO.getDestinations().getFirst().getSections().stream().map(ReportSectionDTO::getFromNode).filter(n -> n.getTypes().contains(NodeType.SOURCE)).findFirst().orElseThrow(); + reportDTO.setSupplier(source); + } return reportDTO; } - private ReportQuotaShareDTO getQuotaShare(List destinations, Map> sections, Premise premise) { - ReportQuotaShareDTO quotaShare = new ReportQuotaShareDTO(); - - var safetyStock = destinations.stream().map(CalculationJobDestination::getSafetyStock).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(destinations.size()), 2, RoundingMode.HALF_UP); - double transportTime = (double) (destinations.stream().map(CalculationJobDestination::getId).map(sections::get).mapToInt(l -> l.stream().mapToInt(CalculationJobRouteSection::getTransitTime).sum()).sum()) / sections.size(); - var airfreight = destinations.stream().map(CalculationJobDestination::getAirFreightShare).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(destinations.size()), 2, RoundingMode.HALF_UP); - - quotaShare.setOverseaShare(premise.getOverseaShare().doubleValue()); - quotaShare.setSafetyStock(safetyStock.doubleValue()); - quotaShare.setTransportTime(transportTime); - quotaShare.setAirFreightShare(airfreight.doubleValue()); - - return quotaShare; - } - - private ReportPackagingDTO getPackagingDTO(List destination, Premise premise) { - ReportPackagingDTO packaging = new ReportPackagingDTO(); + private ReportDestinationDTO getDestinationDTO(CalculationJobDestination destination, List sections, Premise premise) { + var destinationNode = nodeRepository.getByDestinationId(destination.getPremiseDestinationId()).orElseThrow(); var dimensionUnit = premise.getDimensionUnit(); var weightUnit = premise.getWeightUnit(); - packaging.setDimensionUnit(dimensionUnit); - packaging.setWeightUnit(weightUnit); - packaging.setHeight(dimensionUnit.convertFromMM(premise.getIndividualHuHeight()).doubleValue()); - packaging.setWidth(dimensionUnit.convertFromMM(premise.getIndividualHuWidth()).doubleValue()); - packaging.setLength(dimensionUnit.convertFromMM(premise.getIndividualHuLength()).doubleValue()); - packaging.setWeight(weightUnit.convertFromG(premise.getIndividualHuWeight()).doubleValue()); + ReportDestinationDTO destinationDTO = new ReportDestinationDTO(); + destinationDTO.setSections(sections.stream().map(this::getSection).toList()); - packaging.setLayer(destination.stream().mapToInt(CalculationJobDestination::getLayerCount).sum()/destination.size()); - packaging.setUnitCount(premise.getHuUnitCount()); + var totalAnnualCost = sections.stream().map(CalculationJobRouteSection::getAnnualCost).reduce(BigDecimal.ZERO, BigDecimal::add); + destinationDTO.getSections().forEach(s -> { + s.getCost().setPercentage(s.getCost().getTotal().doubleValue()/totalAnnualCost.doubleValue()); + }); + destinationDTO.getSections().forEach(s -> { + s.getDuration().setPercentage(s.getDuration().getTotal().doubleValue()/totalAnnualCost.doubleValue()); + }); - return packaging; - } + destinationDTO.setDestination(nodeTransformer.toNodeDTO(destinationNode)); - private ReportContainerDTO getContainerDTO(List destination, List sections, Premise premise) { - ReportContainerDTO container = new ReportContainerDTO(); + destinationDTO.setDimensionUnit(dimensionUnit); + destinationDTO.setWeightUnit(weightUnit); + destinationDTO.setHeight(dimensionUnit.convertFromMM(premise.getIndividualHuHeight()).doubleValue()); + destinationDTO.setWidth(dimensionUnit.convertFromMM(premise.getIndividualHuWidth()).doubleValue()); + destinationDTO.setLength(dimensionUnit.convertFromMM(premise.getIndividualHuLength()).doubleValue()); + destinationDTO.setWeight(weightUnit.convertFromG(premise.getIndividualHuWeight()).doubleValue()); + + destinationDTO.setLayer(destination.getLayerCount()); + destinationDTO.setUnitCount(premise.getHuUnitCount()); + + destinationDTO.setOverseaShare(premise.getOverseaShare().doubleValue()); + destinationDTO.setSafetyStock(destination.getSafetyStock().doubleValue()); + destinationDTO.setTransportTime(destination.getTotalTransitTime().doubleValue()); + destinationDTO.setAirFreightShare(destination.getAirFreightShare().doubleValue()); CalculationJobRouteSection mainRun = sections.stream().filter(CalculationJobRouteSection::getMainRun).findFirst().orElse(null); - container.setMixed(premise.getHuMixable()); - container.setRate(mainRun == null ? 0 : mainRun.getRate()); - container.setType(ContainerType.valueOf(destination.getFirst().getTransportationType())); - container.setUtilization(destination.getFirst().getContainerUtilization()); - container.setUnitCount(premise.getHuUnitCount()); - container.setWeightExceeded(destination.getFirst().getTransportWeightExceeded()); + destinationDTO.setMixed(premise.getHuMixable()); + destinationDTO.setRate(mainRun == null ? 0 : mainRun.getRate()); + destinationDTO.setType(ContainerType.valueOf(destination.getTransportationType())); + destinationDTO.setUtilization(destination.getContainerUtilization()); + destinationDTO.setUnitCount(premise.getHuUnitCount()); + destinationDTO.setWeightExceeded(destination.getTransportWeightExceeded()); - return container; + destinationDTO.setHsCode(premise.getHsCode()); + + return destinationDTO; } - private ReportQuantityDTO getQuantitiesDTO(CalculationJobDestination destination, List sections) { - ReportQuantityDTO quantity = new ReportQuantityDTO(); + private ReportSectionDTO getSection(CalculationJobRouteSection section) { + ReportSectionDTO sectionDTO = new ReportSectionDTO(); - var destinationNode = nodeRepository.getByDestinationId(destination.getPremiseDestinationId()).orElseThrow(); + sectionDTO.setId(section.getId()); + sectionDTO.setTransportType(section.getTransportType()); + sectionDTO.setFromNode(nodeTransformer.toNodeDTO(routeNodeRepository.getFromNodeBySectionId(section.getPremiseRouteSectionId()).orElseThrow())); + sectionDTO.setRateType(section.getRateType()); - quantity.setQuantity(destination.getAnnualAmount()); - quantity.setDestination(nodeTransformer.toNodeDTO(destinationNode)); - quantity.setRoute(sections.stream().map(this::getRouteEntryDTO).toList()); + var duration = new ReportEntryDTO(); + duration.setTotal(section.getTransitTime()); + sectionDTO.setDuration(duration); - var total = quantity.getRoute().stream().map(ReportRouteEntryDTO::getCost).map(ReportEntryDTO::getTotal).mapToDouble(Number::doubleValue).sum(); - quantity.getRoute().forEach(r -> r.getCost().setPercentage(BigDecimal.valueOf(r.getCost().getTotal().doubleValue() / total).setScale(2, RoundingMode.HALF_UP))); + var cost = new ReportEntryDTO(); + cost.setTotal(section.getAnnualCost()); + sectionDTO.setCost(cost); - return quantity; + return sectionDTO; } - private ReportRouteEntryDTO getRouteEntryDTO(CalculationJobRouteSection routeSection) { - ReportRouteEntryDTO routeEntry = new ReportRouteEntryDTO(); - - var premiseSection = routeSectionRepository.getById(routeSection.getPremiseRouteSectionId()).orElseThrow(); - var sectionNode = nodeRepository.getById(premiseSection.getFromRouteNodeId()).orElseThrow(); - - routeEntry.setName(sectionNode.getExternalMappingId()); - routeEntry.setType(premiseSection.getTransportType()); - routeEntry.setCost(new ReportEntryDTO()); - routeEntry.getCost().setTotal(routeSection.getAnnualCost()); - - return routeEntry; - } private Map getRisk(CalculationJob job, List destination) { Map risk = new HashMap<>(); @@ -158,7 +148,7 @@ 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::getAnnualRiskCost).reduce(BigDecimal.ZERO, BigDecimal::add); worst.setTotal(worstValue); worst.setPercentage(worstValue.divide(totalValue, 2, RoundingMode.HALF_UP)); risk.put("worst_case_cost", worst); diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 20286ed..c0fbf42 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -378,6 +378,8 @@ CREATE TABLE IF NOT EXISTS premise_destination repacking_cost DECIMAL(15, 2) DEFAULT NULL, handling_cost DECIMAL(15, 2) DEFAULT NULL, disposal_cost DECIMAL(15, 2) DEFAULT NULL, + geo_lat DECIMAL(7, 4) CHECK (geo_lat BETWEEN -90 AND 90), + geo_lng DECIMAL(7, 4) CHECK (geo_lng BETWEEN -180 AND 180), FOREIGN KEY (premise_id) REFERENCES premise (id), FOREIGN KEY (destination_node_id) REFERENCES node (id), INDEX idx_destination_node_id (destination_node_id), @@ -424,8 +426,9 @@ CREATE TABLE IF NOT EXISTS premise_route_section to_route_node_id INT NOT NULL, list_position INT NOT NULL, transport_type CHAR(16) CHECK (transport_type IN - ('RAIL', 'SEA', 'ROAD', 'POST-RUN', 'MATRIX', 'D2D')), - rate_d2d DECIMAL(15, 2) COMMENT 'if transport type is D2D this stores the rate in EUR', + ('RAIL', 'SEA', 'ROAD', 'POST-RUN')), + rate_type CHAR(16) CHECK (transport_type IN + ('CONTAINER', 'MATRIX')), is_pre_run BOOLEAN DEFAULT FALSE, is_main_run BOOLEAN DEFAULT FALSE, is_post_run BOOLEAN DEFAULT FALSE, @@ -433,10 +436,6 @@ CREATE TABLE IF NOT EXISTS premise_route_section FOREIGN KEY (premise_route_id) REFERENCES premise_route (id), FOREIGN KEY (from_route_node_id) REFERENCES premise_route_node (id), FOREIGN KEY (to_route_node_id) REFERENCES premise_route_node (id), - CONSTRAINT chk_d2d CHECK ((transport_type != 'D2D' AND rate_d2d IS NULL) OR - (transport_type = 'D2D' AND rate_d2d IS NOT NULL)), - CONSTRAINT chk_post_run CHECK ((transport_type = 'POST-RUN' AND is_post_run IS TRUE) OR - (transport_type != 'POST-RUN' AND rate_d2d IS FALSE)), CONSTRAINT chk_main_run CHECK ((transport_type = 'RAIL' OR transport_type = 'SEA') AND is_main_run IS TRUE), INDEX idx_premise_route_id (premise_route_id), INDEX idx_from_route_node_id (from_route_node_id), @@ -524,8 +523,8 @@ CREATE TABLE IF NOT EXISTS calculation_job_route_section id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, premise_route_section_id INT NOT NULL, calculation_job_destination_id INT NOT NULL, - used_rule CHAR(8) CHECK (used_rule IN - ('CONTAINER', 'MATRIX')), + transport_type CHAR(16) CHECK (transport_type IN + ('RAIL', 'SEA', 'ROAD', 'POST-RUN', 'MATRIX', 'D2D')), is_unmixed_price BOOLEAN DEFAULT FALSE, is_cbm_price BOOLEAN DEFAULT FALSE, is_weight_price BOOLEAN DEFAULT FALSE,