Refined distance calculations and enhanced reporting layout:
- **Backend**: Adjusted `getDistance` implementation to retrieve distances via `DistanceApiService`, with fallback to `fast` algorithm. Updated `DistanceService` to utilize API responses for more accurate calculations. Enhanced `ExcelReportingService` handling for main run containers and mixed premises logic. - **Frontend**: Improved `Report.vue` structure for better readability and modularity. Added logic to conditionally display container details based on the main run's existence.
This commit is contained in:
parent
f7efc9eb81
commit
be1ef5091b
14 changed files with 297 additions and 254 deletions
|
|
@ -1,7 +1,8 @@
|
|||
<template>
|
||||
<div class="report-container">
|
||||
<div class="box-gap">
|
||||
<div class="report-header">{{ shorten(report.supplier.name, 35) }}</div></div>
|
||||
<div class="report-header">{{ shorten(report.supplier.name, 35) }}</div>
|
||||
</div>
|
||||
<div class="report-chart">
|
||||
<report-chart
|
||||
title=""
|
||||
|
|
@ -92,7 +93,10 @@
|
|||
<div class="report-content-row" v-if="((report.costs.air_freight_cost ?? null) !== null)">
|
||||
<div>Air freight costs</div>
|
||||
<div class="report-content-data-cell">{{ report.costs.air_freight_cost.total.toFixed(2) }}</div>
|
||||
<div class="report-content-data-cell">{{ (report.costs.air_freight_cost.percentage * 100).toFixed(2) }}</div>
|
||||
<div class="report-content-data-cell">{{
|
||||
(report.costs.air_freight_cost.percentage * 100).toFixed(2)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
@ -143,7 +147,8 @@
|
|||
<collapsible-box class="report-content-container" variant="border" :title="premise.destination.name"
|
||||
:stretch-content="true" :initially-collapsed="true">
|
||||
<div>
|
||||
<report-route :sections="premise.sections" :destination="premise.destination" :route-section-scale="routeSectionScale[idx]" ></report-route>
|
||||
<report-route :sections="premise.sections" :destination="premise.destination"
|
||||
:route-section-scale="routeSectionScale[idx]"></report-route>
|
||||
|
||||
<div class="report-sub-header">Premisses</div>
|
||||
|
||||
|
|
@ -192,7 +197,10 @@
|
|||
|
||||
<div class="report-content-row">
|
||||
<div>HU dimensions [{{ premise.dimension_unit }}]</div>
|
||||
<div class="report-content-data-cell">{{ toFixedDimension(premise.length, premise.dimension_unit) }} x {{ toFixedDimension(premise.width, premise.dimension_unit) }} x {{ toFixedDimension(premise.height, premise.dimension_unit) }} </div>
|
||||
<div class="report-content-data-cell">{{ toFixedDimension(premise.length, premise.dimension_unit) }} x
|
||||
{{ toFixedDimension(premise.width, premise.dimension_unit) }} x
|
||||
{{ toFixedDimension(premise.height, premise.dimension_unit) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="report-content-row">
|
||||
|
|
@ -212,22 +220,22 @@
|
|||
|
||||
<div class="report-content-row">
|
||||
<div>Stacked layers</div>
|
||||
<div class="report-content-data-cell">{{ premise.layer }} </div>
|
||||
<div class="report-content-data-cell">{{ hasMainRun(premise.sections) ? premise.layer : '-' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="report-content-row">
|
||||
<div>Container unit count</div>
|
||||
<div class="report-content-data-cell">{{ premise.unit_count * premise.hu_unit_count }} </div>
|
||||
<div class="report-content-data-cell">{{hasMainRun(premise.sections) ? (premise.unit_count * premise.hu_unit_count) : '-' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="report-content-row">
|
||||
<div>Container type</div>
|
||||
<div class="report-content-data-cell">{{ getContainerTypeName(premise.container_type) }} </div>
|
||||
<div class="report-content-data-cell">{{hasMainRun(premise.sections) ? getContainerTypeName(premise.container_type) : '-' }}</div>
|
||||
</div>
|
||||
|
||||
<div class="report-content-row">
|
||||
<div>Limiting factor</div>
|
||||
<div class="report-content-data-cell">{{ premise.weight_exceeded ? 'Weight' : 'Volume' }} </div>
|
||||
<div class="report-content-data-cell">{{hasMainRun(premise.sections) ? premise.weight_exceeded ? 'Weight' : 'Volume' : '-'}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -265,6 +273,9 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
hasMainRun(sections) {
|
||||
return sections.some(section => section.transport_type === 'SEA' || section.transport_type === 'RAIL');
|
||||
},
|
||||
shorten(text, length) {
|
||||
if (text !== null && text !== undefined && text.length > length) {
|
||||
return `${text.substring(0, length - 3)} …`;
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ export default {
|
|||
return this.modalType ? this.componentsData[this.modalType] : null;
|
||||
},
|
||||
showProcessingModal() {
|
||||
return this.premiseEditStore.showProcessingModal;
|
||||
return this.premiseEditStore.showProcessingModal || this.showCalculationModal;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
@ -224,7 +224,8 @@ export default {
|
|||
},
|
||||
editIds: null,
|
||||
dataSourceId: null,
|
||||
processingMessage: "Please wait. Calculating routes ...",
|
||||
processingMessage: "Please wait. Calculating ...",
|
||||
showCalculationModal: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -244,6 +245,7 @@ export default {
|
|||
}
|
||||
},
|
||||
async startCalculation() {
|
||||
this.showCalculationModal = true;
|
||||
const error = await this.premiseEditStore.startCalculation();
|
||||
|
||||
if (error !== null) {
|
||||
|
|
@ -258,6 +260,7 @@ export default {
|
|||
} else {
|
||||
this.closeMassEdit()
|
||||
}
|
||||
this.showCalculationModal = false;
|
||||
},
|
||||
closeMassEdit() {
|
||||
this.$router.push({name: "calculation-list"});
|
||||
|
|
|
|||
|
|
@ -86,6 +86,13 @@
|
|||
<h3 class="sub-header">Destinations & routes</h3>
|
||||
<destination-list-view></destination-list-view>
|
||||
|
||||
<modal :z-index="3000" :state="showProcessingModal">
|
||||
<div class="edit-calculation-spinner-container space-around">
|
||||
<spinner></spinner>
|
||||
<span>{{ processingMessage }}</span>
|
||||
</div>
|
||||
</modal>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -131,6 +138,8 @@ export default {
|
|||
traceModal: false,
|
||||
bulkEditQuery: null,
|
||||
id: null,
|
||||
processingMessage: "Please wait. Calculating ...",
|
||||
showCalculationModal: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -140,15 +149,18 @@ export default {
|
|||
},
|
||||
fromMassEdit() {
|
||||
return this.bulkEditQuery !== null;
|
||||
}
|
||||
},
|
||||
showProcessingModal() {
|
||||
return this.premiseEditStore.showProcessingModal || this.showCalculationModal;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
async startCalculation() {
|
||||
this.showCalculationModal = true;
|
||||
const error = await this.premiseEditStore.startCalculation();
|
||||
|
||||
|
||||
if (error !== null) {
|
||||
|
||||
this.$refs.toast.addToast({
|
||||
icon: 'warning',
|
||||
message: error.message,
|
||||
|
|
@ -159,6 +171,8 @@ export default {
|
|||
} else {
|
||||
this.close();
|
||||
}
|
||||
|
||||
this.showCalculationModal = false;
|
||||
},
|
||||
close() {
|
||||
if (this.bulkEditQuery) {
|
||||
|
|
@ -181,17 +195,6 @@ export default {
|
|||
success = await this.premiseEditStore.savePackaging();
|
||||
}
|
||||
|
||||
|
||||
// if(success) {
|
||||
// this.$refs.toast.addToast({
|
||||
// icon: 'floppy-disk',
|
||||
// message: `Changes on ${type} saved.`,
|
||||
//
|
||||
// variant: 'primary',
|
||||
// duration: 3000
|
||||
// })
|
||||
// }
|
||||
|
||||
},
|
||||
updateMaterial(id, action) {
|
||||
console.log(id, action);
|
||||
|
|
@ -287,11 +290,18 @@ export default {
|
|||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.space-around {
|
||||
margin: 3rem;
|
||||
}
|
||||
|
||||
.edit-calculation-spinner-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1 1 30rem;
|
||||
gap: 3.6rem;
|
||||
flex: 1 1 auto;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.edit-calculation-spinner {
|
||||
|
|
|
|||
|
|
@ -599,6 +599,8 @@ export const usePremiseEditStore = defineStore('premiseEdit', {
|
|||
} else {
|
||||
const id = node.id;
|
||||
|
||||
this.processDestinationMassEdit = true;
|
||||
|
||||
|
||||
const toBeUpdated = this.destinations.fromMassEditView ? this.destinations.premise_ids : this.premisses?.filter(p => p.selected).map(p => p.id);
|
||||
|
||||
|
|
@ -611,6 +613,7 @@ export const usePremiseEditStore = defineStore('premiseEdit', {
|
|||
const {data: destinations} = await performRequest(this, 'POST', url, body).catch(e => {
|
||||
this.loading = false;
|
||||
this.selectedLoading = false;
|
||||
this.processDestinationMassEdit = false;
|
||||
throw e;
|
||||
});
|
||||
|
||||
|
|
@ -624,6 +627,8 @@ export const usePremiseEditStore = defineStore('premiseEdit', {
|
|||
this.destinations.destinations.push(mappedDestination);
|
||||
}
|
||||
|
||||
this.processDestinationMassEdit = false;
|
||||
|
||||
return mappedIds;
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -39,9 +39,10 @@ export const useReportsStore = defineStore('reports', {
|
|||
const params = new URLSearchParams();
|
||||
params.append('material', this.materialId);
|
||||
params.append('sources', this.supplierIds);
|
||||
params.append('userSources', this.userSupplierIds);
|
||||
|
||||
const url = `${config.backendUrl}/reports/download/${params.size === 0 ? '' : '?'}${params.toString()}`;
|
||||
const fileName = `report_${this.materialId}_${this.supplierIds.join('_')}.xlsx`;
|
||||
const fileName = `report_${this.materialId}_${this.supplierIds.join('_')}_u${this.userSupplierIds.join('_')}.xlsx`;
|
||||
await performDownload(url,fileName);
|
||||
},
|
||||
reset() {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class SecurityConfig {
|
|||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
|
||||
.requestMatchers("/actuator/health").permitAll()
|
||||
.requestMatchers("/actuator/**").authenticated()
|
||||
.requestMatchers("/actuator/**").hasRole("SERVICE")
|
||||
.requestMatchers("/oauth2/token").permitAll()
|
||||
.requestMatchers("/api/**").authenticated()
|
||||
.requestMatchers("/api/dev/**").denyAll()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import org.springframework.web.client.RestTemplate;
|
|||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.net.URI;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ public class DistanceApiService {
|
|||
}
|
||||
|
||||
public Optional<Distance> getDistance(Node from, Node to) {
|
||||
|
||||
if (from == null || to == null) {
|
||||
logger.warn("Source or destination node is null");
|
||||
return Optional.empty();
|
||||
|
|
@ -46,7 +48,6 @@ public class DistanceApiService {
|
|||
return Optional.empty();
|
||||
}
|
||||
|
||||
// Check if distance exists in database and is valid
|
||||
Optional<Distance> cachedDistance = distanceMatrixRepository.getDistance(from, to);
|
||||
|
||||
if (cachedDistance.isPresent()) {
|
||||
|
|
@ -54,12 +55,10 @@ public class DistanceApiService {
|
|||
return cachedDistance;
|
||||
}
|
||||
|
||||
// Distance not found or stale, fetch from Azure Maps
|
||||
logger.info("Fetching distance from Azure Maps for nodes {} to {}", from.getId(), to.getId());
|
||||
logger.debug("Fetching distance from Azure Maps for nodes {} to {}", from.getId(), to.getId());
|
||||
Optional<Distance> fetchedDistance = fetchDistanceFromAzureMaps(from, to);
|
||||
|
||||
if (fetchedDistance.isPresent()) {
|
||||
// Store in database
|
||||
distanceMatrixRepository.saveDistance(fetchedDistance.get());
|
||||
return fetchedDistance;
|
||||
}
|
||||
|
|
@ -69,18 +68,19 @@ public class DistanceApiService {
|
|||
|
||||
private Optional<Distance> fetchDistanceFromAzureMaps(Node from, Node to) {
|
||||
try {
|
||||
String url = UriComponentsBuilder.fromHttpUrl(AZURE_MAPS_ROUTE_API)
|
||||
String url = UriComponentsBuilder.fromUriString(AZURE_MAPS_ROUTE_API)
|
||||
.queryParam("api-version", "1.0")
|
||||
.queryParam("subscription-key", subscriptionKey)
|
||||
.queryParam("query", String.format("%s,%s:%s,%s",
|
||||
from.getGeoLat(), from.getGeoLng(),
|
||||
to.getGeoLat(), to.getGeoLng()))
|
||||
.encode()
|
||||
.toUriString();
|
||||
|
||||
RouteDirectionsResponse response = restTemplate.getForObject(url, RouteDirectionsResponse.class);
|
||||
|
||||
if (response != null && response.getRoutes() != null && !response.getRoutes().isEmpty()) {
|
||||
Integer distanceInMeters = response.getRoutes().get(0).getSummary().getLengthInMeters();
|
||||
Integer distanceInMeters = response.getRoutes().getFirst().getSummary().getLengthInMeters();
|
||||
|
||||
Distance distance = new Distance();
|
||||
distance.setFromNodeId(from.getId());
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import de.avatic.lcc.model.db.nodes.Location;
|
|||
import de.avatic.lcc.model.db.nodes.Node;
|
||||
import de.avatic.lcc.repositories.DistanceMatrixRepository;
|
||||
import de.avatic.lcc.repositories.country.CountryRepository;
|
||||
import de.avatic.lcc.service.api.DistanceApiService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
|
|
@ -14,20 +15,21 @@ public class DistanceService {
|
|||
private static final double EARTH_RADIUS = 6371.0;
|
||||
private final DistanceMatrixRepository distanceMatrixRepository;
|
||||
private final CountryRepository countryRepository;
|
||||
private final DistanceApiService distanceApiService;
|
||||
|
||||
public DistanceService(DistanceMatrixRepository distanceMatrixRepository, CountryRepository countryRepository) {
|
||||
public DistanceService(DistanceMatrixRepository distanceMatrixRepository, CountryRepository countryRepository, DistanceApiService distanceApiService) {
|
||||
this.distanceMatrixRepository = distanceMatrixRepository;
|
||||
this.countryRepository = countryRepository;
|
||||
this.distanceApiService = distanceApiService;
|
||||
}
|
||||
|
||||
public double getDistance(Node src, Node dest, boolean fast) {
|
||||
if (fast) return getDistanceFast(src, dest);
|
||||
|
||||
var distance = distanceMatrixRepository.getDistance(src, dest);
|
||||
|
||||
// TODO do a api call if empty!.
|
||||
return distance.map(value -> value.getDistance().intValue()).orElse(0);
|
||||
var distance = distanceApiService.getDistance(src, dest);
|
||||
if (distance.isEmpty()) return getDistanceFast(src, dest);
|
||||
|
||||
return distance.map(value -> value.getDistance().intValue()/1000).orElse(0);
|
||||
}
|
||||
|
||||
public double getDistanceFast(Integer srcCountryId, Location src, Integer destCountryId, Location dest ) {
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ public class RoutingService {
|
|||
}
|
||||
|
||||
finalSection.setRate(matrixRate);
|
||||
finalSection.setApproxDistance(distanceService.getDistance(container.getSourceNode(), toNode, true));
|
||||
finalSection.setApproxDistance(distanceService.getDistance(container.getSourceNode(), toNode, false));
|
||||
rates.add(finalSection);
|
||||
}
|
||||
|
||||
|
|
@ -699,7 +699,7 @@ public class RoutingService {
|
|||
|
||||
if (matrixRate.isPresent()) {
|
||||
matrixRateObj.setRate(matrixRate.get());
|
||||
matrixRateObj.setApproxDistance(distanceService.getDistance(startNode, endNode, true));
|
||||
matrixRateObj.setApproxDistance(distanceService.getDistance(startNode, endNode, false));
|
||||
container.getRates().add(matrixRateObj);
|
||||
return matrixRateObj;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public class RouteSectionCostCalculationService {
|
|||
Node fromNode = nodeRepository.getById(premise.getSupplierNodeId()).orElseThrow();
|
||||
Node toNode = nodeRepository.getById(destination.getDestinationNodeId()).orElseThrow();
|
||||
|
||||
double distance = distanceService.getDistance(fromNode, toNode, true);
|
||||
double distance = distanceService.getDistance(fromNode, toNode, false);
|
||||
result.setDistance(BigDecimal.valueOf(distance));
|
||||
|
||||
// Get rate and transit time
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ public class PreCalculationCheckService {
|
|||
|
||||
var validDaysInt = Integer.parseInt(validDays.get().getCurrentValue());
|
||||
|
||||
if(!period.getStartDate().plusDays((long) validDaysInt * renewals).isAfter(LocalDateTime.now()))
|
||||
if(!period.getStartDate().plusDays((((long) validDaysInt * renewals)+validDaysInt)).isAfter(LocalDateTime.now()))
|
||||
throw new PremiseValidationError("There are no valid rates for the given date. Please contact your administrator.");
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package de.avatic.lcc.service.report;
|
||||
|
||||
import de.avatic.lcc.dto.generic.NodeDTO;
|
||||
import de.avatic.lcc.dto.generic.TransportType;
|
||||
import de.avatic.lcc.dto.report.ReportDTO;
|
||||
import de.avatic.lcc.dto.report.ReportDestinationDTO;
|
||||
import de.avatic.lcc.dto.report.ReportEntryDTO;
|
||||
|
|
@ -145,6 +146,9 @@ public class ExcelReportingService {
|
|||
}
|
||||
|
||||
private void flattenDestination(ReportDestinationDTO destination) {
|
||||
|
||||
var hasMainRun = destination.getSections().stream().anyMatch(s -> s.getTransportType().equals(TransportType.RAIL) || s.getTransportType().equals(TransportType.SEA));
|
||||
|
||||
addData(DESTINATION_NAME, destination.getDestination().getName());
|
||||
addData(DESTINATION_ADDRESS, destination.getDestination().getAddress());
|
||||
|
||||
|
|
@ -152,6 +156,7 @@ public class ExcelReportingService {
|
|||
addData(DESTINATION_HS_CODE, destination.getHsCode());
|
||||
addData(DESTINATION_TARIFF_RATE, destination.getTariffRate().toString());
|
||||
addData(DESTINATION_OVERSHARE, destination.getOverseaShare().toString());
|
||||
|
||||
if(destination.getAirFreightShare() != null)
|
||||
addData(DESTINATION_AIR_FREIGHT_SHARE, destination.getAirFreightShare().toString());
|
||||
addData(DESTINATION_TRANSPORT_TIME, destination.getTransportTime().toString());
|
||||
|
|
@ -164,14 +169,14 @@ public class ExcelReportingService {
|
|||
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_LAYER, !hasMainRun ? "-" : 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());
|
||||
addData(DESTINATION_CONTAINER_UNIT_COUNT, !hasMainRun ? "-" : destination.getUnitCount().toString());
|
||||
addData(DESTINATION_CONTAINER_UTILIZATION, !hasMainRun ? "-" : destination.getUtilization().toString());
|
||||
addData(DESTINATION_CONTAINER_TYPE, !hasMainRun ? "-" : destination.getType().toString());
|
||||
addData(DESTINATION_CONTAINER_WEIGHT_EXCEEDED, !hasMainRun ? "-" : destination.getWeightExceeded().toString());
|
||||
addData(DESTINATION_CONTAINER_RATE, !hasMainRun ? "-" : destination.getRate().toString());
|
||||
addData(DESTINATION_MIXED, !hasMainRun ? "-" : destination.getMixed().toString());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ 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.db.calculations.CalculationJob;
|
||||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.repositories.calculation.CalculationJobRepository;
|
||||
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
|
||||
|
|
@ -58,9 +59,13 @@ public class ReportingService {
|
|||
var periodId = tuple.get().periodId();
|
||||
var setId = tuple.get().propertySetId();
|
||||
|
||||
//TODO check user node id and node id for null
|
||||
|
||||
var jobs = new ArrayList<>(nodeIds.stream().map(nodeId -> calculationJobRepository.getCalculationJobWithJobStateValid(periodId, setId, nodeId, materialId)).filter(Optional::isPresent).map(Optional::get).toList());
|
||||
var jobs = new ArrayList<CalculationJob>();
|
||||
|
||||
if(!nodeIds.isEmpty())
|
||||
jobs.addAll(nodeIds.stream().map(nodeId -> calculationJobRepository.getCalculationJobWithJobStateValid(periodId, setId, nodeId, materialId)).filter(Optional::isPresent).map(Optional::get).toList());
|
||||
|
||||
if(!userNodeIds.isEmpty())
|
||||
jobs.addAll(userNodeIds.stream().map(nodeId -> calculationJobRepository.getCalculationJobWithJobStateValidUserNodeId(periodId, setId,nodeId ,materialId)).filter(Optional::isPresent).map(Optional::get).toList());
|
||||
|
||||
return jobs.stream().map(reportTransformer::toReportDTO).toList();
|
||||
|
|
|
|||
|
|
@ -190,6 +190,8 @@ public class ReportTransformer {
|
|||
destinationDTO.setWeight(weightUnit.convertFromG(premise.getIndividualHuWeight()));
|
||||
destinationDTO.setHuUnitCount(premise.getHuUnitCount());
|
||||
|
||||
CalculationJobRouteSection mainRun = sections.stream().filter(CalculationJobRouteSection::getMainRun).findFirst().orElse(null);
|
||||
|
||||
destinationDTO.setLayer(destination.getLayerCount());
|
||||
|
||||
destinationDTO.setOverseaShare(premise.getOverseaShare().doubleValue());
|
||||
|
|
@ -199,7 +201,6 @@ public class ReportTransformer {
|
|||
if (includeAirfreight)
|
||||
destinationDTO.setAirFreightShare(destination.getAirFreightShare().doubleValue());
|
||||
|
||||
CalculationJobRouteSection mainRun = sections.stream().filter(CalculationJobRouteSection::getMainRun).findFirst().orElse(null);
|
||||
|
||||
destinationDTO.setMixed(premise.getHuMixable());
|
||||
destinationDTO.setRate(mainRun == null ? 0 : mainRun.getRate());
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue