Remove unused service classes and refactor mappings
Deleted `DestinationService` and `ValidityPeriodService` as they were obsolete. Refactored several classes, including `PremisesService` and `MatrixRateExcelMapper`, to improve package alignment and streamline dependencies. Enhanced `PremiseRepository` with cleaner query construction, better parameter handling, and support for resolving chains of predecessors in `NodeRepository`.
This commit is contained in:
parent
11bdf3b948
commit
e4ab851d7f
47 changed files with 1319 additions and 355 deletions
|
|
@ -9,10 +9,12 @@ import de.avatic.lcc.dto.calculation.DestinationDTO;
|
||||||
import de.avatic.lcc.dto.calculation.edit.destination.DestinationUpdateDTO;
|
import de.avatic.lcc.dto.calculation.edit.destination.DestinationUpdateDTO;
|
||||||
import de.avatic.lcc.dto.calculation.edit.masterData.*;
|
import de.avatic.lcc.dto.calculation.edit.masterData.*;
|
||||||
import de.avatic.lcc.dto.calculation.PremiseDTO;
|
import de.avatic.lcc.dto.calculation.PremiseDTO;
|
||||||
import de.avatic.lcc.service.calculation.DestinationService;
|
import de.avatic.lcc.service.access.DestinationService;
|
||||||
|
import de.avatic.lcc.service.calculation.ChangeMaterialService;
|
||||||
|
import de.avatic.lcc.service.calculation.ChangeSupplierService;
|
||||||
import de.avatic.lcc.service.calculation.PremiseSearchStringAnalyzerService;
|
import de.avatic.lcc.service.calculation.PremiseSearchStringAnalyzerService;
|
||||||
import de.avatic.lcc.service.calculation.PremiseCreationService;
|
import de.avatic.lcc.service.calculation.PremiseCreationService;
|
||||||
import de.avatic.lcc.service.calculation.PremisesService;
|
import de.avatic.lcc.service.access.PremisesService;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
@ -27,12 +29,16 @@ public class CalculationController {
|
||||||
private final PremisesService premisesServices;
|
private final PremisesService premisesServices;
|
||||||
private final PremiseCreationService premiseCreationService;
|
private final PremiseCreationService premiseCreationService;
|
||||||
private final DestinationService destinationService;
|
private final DestinationService destinationService;
|
||||||
|
private final ChangeSupplierService changeSupplierService;
|
||||||
|
private final ChangeMaterialService changeMaterialService;
|
||||||
|
|
||||||
public CalculationController(PremiseSearchStringAnalyzerService premiseSearchStringAnalyzerService, PremisesService premisesServices, PremiseCreationService premiseCreationService, DestinationService destinationService) {
|
public CalculationController(PremiseSearchStringAnalyzerService premiseSearchStringAnalyzerService, PremisesService premisesServices, PremiseCreationService premiseCreationService, DestinationService destinationService, ChangeSupplierService changeSupplierService, ChangeMaterialService changeMaterialService) {
|
||||||
this.premiseSearchStringAnalyzerService = premiseSearchStringAnalyzerService;
|
this.premiseSearchStringAnalyzerService = premiseSearchStringAnalyzerService;
|
||||||
this.premisesServices = premisesServices;
|
this.premisesServices = premisesServices;
|
||||||
this.premiseCreationService = premiseCreationService;
|
this.premiseCreationService = premiseCreationService;
|
||||||
this.destinationService = destinationService;
|
this.destinationService = destinationService;
|
||||||
|
this.changeSupplierService = changeSupplierService;
|
||||||
|
this.changeMaterialService = changeMaterialService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/view")
|
@GetMapping("/view")
|
||||||
|
|
@ -68,22 +74,22 @@ public class CalculationController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/packaging")
|
@PutMapping("/packaging")
|
||||||
public ResponseEntity<HashMap<String, String>> updatePackaging(PackagingUpdateDTO packagingDTO) {
|
public ResponseEntity<HashMap<String, String>> updatePackaging(@RequestBody PackagingUpdateDTO packagingDTO) {
|
||||||
return ResponseEntity.ok(premisesServices.updatePackaging(packagingDTO));
|
return ResponseEntity.ok(premisesServices.updatePackaging(packagingDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/material")
|
@PutMapping("/material")
|
||||||
public ResponseEntity<HashMap<String, String>> updateMaterial(MaterialUpdateDTO materialUpdateDTO) {
|
public ResponseEntity<HashMap<String, String>> updateMaterial(@RequestBody MaterialUpdateDTO materialUpdateDTO) {
|
||||||
return ResponseEntity.ok(premisesServices.updateMaterial(materialUpdateDTO));
|
return ResponseEntity.ok(premisesServices.updateMaterial(materialUpdateDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/price")
|
@PutMapping("/price")
|
||||||
public ResponseEntity<HashMap<String, String>> updatePrice(PriceUpdateDTO priceUpdateDTO) {
|
public ResponseEntity<HashMap<String, String>> updatePrice(@RequestBody PriceUpdateDTO priceUpdateDTO) {
|
||||||
return ResponseEntity.ok(premisesServices.updatePrice(priceUpdateDTO));
|
return ResponseEntity.ok(premisesServices.updatePrice(priceUpdateDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/destination")
|
@PostMapping("/destination")
|
||||||
public ResponseEntity<HashMap<Integer, DestinationDTO>> createDestination(DestinationCreateDTO destinationCreateDTO) {
|
public ResponseEntity<HashMap<Integer, DestinationDTO>> createDestination(@RequestBody DestinationCreateDTO destinationCreateDTO) {
|
||||||
return ResponseEntity.ok(destinationService.createDestination(destinationCreateDTO));
|
return ResponseEntity.ok(destinationService.createDestination(destinationCreateDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,18 +106,18 @@ public class CalculationController {
|
||||||
|
|
||||||
@DeleteMapping("/destination({id}")
|
@DeleteMapping("/destination({id}")
|
||||||
public ResponseEntity<Void> deleteDestination(@PathVariable Integer id) {
|
public ResponseEntity<Void> deleteDestination(@PathVariable Integer id) {
|
||||||
destinationService.deleteDestination(id);
|
destinationService.deleteDestinationById(id, false);
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/supplier")
|
@PutMapping("/supplier")
|
||||||
public ResponseEntity<List<PremiseDetailDTO>> setSupplier(SetDataDTO setSupplierDTO) {
|
public ResponseEntity<List<PremiseDetailDTO>> setSupplier(@RequestBody SetDataDTO setSupplierDTO) {
|
||||||
return ResponseEntity.ok(premisesServices.setSupplier(setSupplierDTO));
|
return ResponseEntity.ok(changeSupplierService.setSupplier(setSupplierDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/material")
|
@PutMapping("/material")
|
||||||
public ResponseEntity<List<PremiseDetailDTO>> setMaterial(SetDataDTO setMaterialDTO) {
|
public ResponseEntity<List<PremiseDetailDTO>> setMaterial(SetDataDTO setMaterialDTO) {
|
||||||
return ResponseEntity.ok(premisesServices.setMaterial(setMaterialDTO));
|
return ResponseEntity.ok(changeMaterialService.setMaterial(setMaterialDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package de.avatic.lcc.controller.configuration;
|
||||||
import de.avatic.lcc.dto.configuration.countries.view.CountryDetailDTO;
|
import de.avatic.lcc.dto.configuration.countries.view.CountryDetailDTO;
|
||||||
import de.avatic.lcc.dto.generic.CountryDTO;
|
import de.avatic.lcc.dto.generic.CountryDTO;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.service.configuration.CountryService;
|
import de.avatic.lcc.service.access.CountryService;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
package de.avatic.lcc.controller.configuration;
|
package de.avatic.lcc.controller.configuration;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
||||||
import de.avatic.lcc.dto.configuration.material.update.MaterialUpdateDTO;
|
|
||||||
import de.avatic.lcc.dto.generic.MaterialDTO;
|
import de.avatic.lcc.dto.generic.MaterialDTO;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.service.configuration.MaterialService;
|
import de.avatic.lcc.service.access.MaterialService;
|
||||||
import de.avatic.lcc.util.Check;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
package de.avatic.lcc.controller.configuration;
|
package de.avatic.lcc.controller.configuration;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.configuration.nodes.userNodes.LocateNodeDTO;
|
import de.avatic.lcc.dto.configuration.nodes.userNodes.LocateNodeDTO;
|
||||||
import de.avatic.lcc.dto.generic.LocationDTO;
|
|
||||||
import de.avatic.lcc.dto.generic.NodeDTO;
|
import de.avatic.lcc.dto.generic.NodeDTO;
|
||||||
import de.avatic.lcc.dto.configuration.nodes.view.NodeDetailDTO;
|
import de.avatic.lcc.dto.configuration.nodes.view.NodeDetailDTO;
|
||||||
import de.avatic.lcc.dto.configuration.nodes.update.NodeUpdateDTO;
|
import de.avatic.lcc.dto.configuration.nodes.update.NodeUpdateDTO;
|
||||||
import de.avatic.lcc.dto.generic.NodeType;
|
import de.avatic.lcc.dto.generic.NodeType;
|
||||||
import de.avatic.lcc.dto.configuration.nodes.userNodes.AddUserNodeDTO;
|
import de.avatic.lcc.dto.configuration.nodes.userNodes.AddUserNodeDTO;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.repositories.users.UserNodeRepository;
|
|
||||||
import de.avatic.lcc.service.GeoApiService;
|
import de.avatic.lcc.service.GeoApiService;
|
||||||
import de.avatic.lcc.service.configuration.NodeService;
|
import de.avatic.lcc.service.access.NodeService;
|
||||||
|
import de.avatic.lcc.service.access.UserNodeService;
|
||||||
import de.avatic.lcc.util.Check;
|
import de.avatic.lcc.util.Check;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
@ -23,11 +22,12 @@ public class NodeController {
|
||||||
|
|
||||||
private final NodeService nodeService;
|
private final NodeService nodeService;
|
||||||
private final GeoApiService geoApiService;
|
private final GeoApiService geoApiService;
|
||||||
|
private final UserNodeService userNodeService;
|
||||||
|
|
||||||
public NodeController(NodeService nodeService, GeoApiService geoApiService) {
|
public NodeController(NodeService nodeService, GeoApiService geoApiService, UserNodeService userNodeService) {
|
||||||
this.nodeService = nodeService;
|
this.nodeService = nodeService;
|
||||||
this.geoApiService = geoApiService;
|
this.geoApiService = geoApiService;
|
||||||
|
this.userNodeService = userNodeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
|
|
@ -71,7 +71,7 @@ public class NodeController {
|
||||||
|
|
||||||
@PutMapping("/")
|
@PutMapping("/")
|
||||||
public ResponseEntity<Void> addUserNode(@RequestParam AddUserNodeDTO node) {
|
public ResponseEntity<Void> addUserNode(@RequestParam AddUserNodeDTO node) {
|
||||||
nodeService.addUserNode(node);
|
userNodeService.addUserNode(node);
|
||||||
return ResponseEntity.ok().build();
|
return ResponseEntity.ok().build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ package de.avatic.lcc.controller.configuration;
|
||||||
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
||||||
import de.avatic.lcc.dto.generic.PropertyDTO;
|
import de.avatic.lcc.dto.generic.PropertyDTO;
|
||||||
import de.avatic.lcc.model.country.IsoCode;
|
import de.avatic.lcc.model.country.IsoCode;
|
||||||
import de.avatic.lcc.service.configuration.CountryService;
|
import de.avatic.lcc.service.access.CountryService;
|
||||||
import de.avatic.lcc.service.configuration.PropertyService;
|
import de.avatic.lcc.service.access.PropertyService;
|
||||||
import de.avatic.lcc.service.configuration.PropertyApprovalService;
|
import de.avatic.lcc.service.configuration.PropertyApprovalService;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ import de.avatic.lcc.dto.configuration.matrixrates.MatrixRateDTO;
|
||||||
import de.avatic.lcc.dto.configuration.rates.ContainerRateDTO;
|
import de.avatic.lcc.dto.configuration.rates.ContainerRateDTO;
|
||||||
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.service.configuration.ContainerRateService;
|
import de.avatic.lcc.service.access.ContainerRateService;
|
||||||
import de.avatic.lcc.service.configuration.MatrixRateService;
|
import de.avatic.lcc.service.access.MatrixRateService;
|
||||||
import de.avatic.lcc.service.configuration.RateApprovalService;
|
import de.avatic.lcc.service.configuration.RateApprovalService;
|
||||||
import de.avatic.lcc.service.configuration.ValidityPeriodService;
|
import de.avatic.lcc.service.access.ValidityPeriodService;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package de.avatic.lcc.controller.custom;
|
package de.avatic.lcc.controller.custom;
|
||||||
|
|
||||||
import de.avatic.lcc.service.calculation.CustomApiService;
|
import de.avatic.lcc.service.CustomApiService;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,19 @@ public class SetDataDTO {
|
||||||
@JsonProperty("supplier_node_id", required = false)
|
@JsonProperty("supplier_node_id", required = false)
|
||||||
Integer supplierNodeId;
|
Integer supplierNodeId;
|
||||||
|
|
||||||
|
@JsonProperty("is_user_supplier_node")
|
||||||
|
boolean isUserSupplierNode;
|
||||||
|
|
||||||
@JsonProperty(value = "material_id", required = false)
|
@JsonProperty(value = "material_id", required = false)
|
||||||
Integer materialId;
|
Integer materialId;
|
||||||
|
|
||||||
|
public boolean isUserSupplierNode() {
|
||||||
|
return isUserSupplierNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserSupplierNode(boolean userSupplierNode) {
|
||||||
|
isUserSupplierNode = userSupplierNode;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getMaterialId() {
|
public Integer getMaterialId() {
|
||||||
return materialId;
|
return materialId;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,47 @@
|
||||||
package de.avatic.lcc.dto.calculation.edit.destination;
|
package de.avatic.lcc.dto.calculation.edit.destination;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
public class DestinationUpdateDTO {
|
public class DestinationUpdateDTO {
|
||||||
|
|
||||||
|
@JsonProperty("repacking_cost")
|
||||||
|
private Number repackingCost;
|
||||||
|
@JsonProperty("handling_cost")
|
||||||
|
private Number handlingCost;
|
||||||
|
@JsonProperty("disposal_cost")
|
||||||
|
private Number disposalCost;
|
||||||
|
@JsonProperty("route_selected_id")
|
||||||
|
private Integer routeSelectedId;
|
||||||
|
|
||||||
|
public Number getRepackingCost() {
|
||||||
|
return repackingCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepackingCost(Number repackingCost) {
|
||||||
|
this.repackingCost = repackingCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number getHandlingCost() {
|
||||||
|
return handlingCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHandlingCost(Number handlingCost) {
|
||||||
|
this.handlingCost = handlingCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number getDisposalCost() {
|
||||||
|
return disposalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisposalCost(Number disposalCost) {
|
||||||
|
this.disposalCost = disposalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRouteSelectedId() {
|
||||||
|
return routeSelectedId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRouteSelectedId(Integer routeSelectedId) {
|
||||||
|
this.routeSelectedId = routeSelectedId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package de.avatic.lcc.model.properties;
|
||||||
|
|
||||||
|
public enum PackagingPropertyMappingId {
|
||||||
|
STACKABLE, MIXABLE, RUST_PREVENTION
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
package de.avatic.lcc.model.properties;
|
||||||
|
|
||||||
|
public enum SystemPropertyMappingId {
|
||||||
|
|
||||||
|
WORKDAYS("Annual working days", "210"),
|
||||||
|
INTEREST_RATE("Interest rate inventory [%]", "12%"),
|
||||||
|
FCA_FEE("FCA fee [%]", "0,20%"),
|
||||||
|
TARIFF_RATE("Default customs duty [%]", "3,0%"),
|
||||||
|
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"),
|
||||||
|
RADIUS_REGION("Metropolition region size (diameter) [km]", "20"),
|
||||||
|
FREQ_MIN("Min delivery frequency / year for containtrer transports", "3"),
|
||||||
|
FREQ_MAX("Max delivery frequency / year for containtrer transports", "50"),
|
||||||
|
TEU_LOAD("Max load of 20' container [kg]", "20000"),
|
||||||
|
FEU_LOAD("Max load of 40' container [kg]", "21000"),
|
||||||
|
|
||||||
|
|
||||||
|
AIR_PRECARRIAGE("Pre-carriage [EUR/kg]", "0,10 €"),
|
||||||
|
AIR_HANDLING("Pre-carriage handling [EUR]", "80,00 €"),
|
||||||
|
AIR_MAINCARRIAGE("Main carriage [EUR/kg]", "3,50 €"),
|
||||||
|
AIR_HANDOVER_FEE("Hand over fee [EUR]", "35,00 €"),
|
||||||
|
AIR_CUSTOM_FEE("Customs clearance fee [EUR]", "45,00 €"),
|
||||||
|
AIR_ONCARRIAGE("On-carriage [EUR/kg]", "0,20 €"),
|
||||||
|
AIR_TERMINAL_FEE("Terminal handling fee [EUR/kg]", "0,20 €"),
|
||||||
|
|
||||||
|
|
||||||
|
KLT_HANDLING("GR handling KLT [EUR/HU]", "0,71 €"),
|
||||||
|
GLT_HANDLING("GR handling GLT [EUR/HU]", "3,50 €"),
|
||||||
|
BOOKING("GLT/KLT booking & document handling [EUR/GR]", "3,50 €"),
|
||||||
|
GLT_RELEASE("GLT release from storage [EUR/GLT release]", "2,23 €"),
|
||||||
|
KLT_RELEASE("KLT release from storage [EUR/KLT release]", "1,12 €"),
|
||||||
|
GLT_DISPATCH("GLT dispatch [EUR/GLT dispatch]", "1,61 €"),
|
||||||
|
KLT_DISPATCH("KLT dispacth [EUR/KLT dispatch]", "0,33 €"),
|
||||||
|
KLT_REPACK_S("Repacking KLT, HU <15kg [EUR/HU]", "2,08 €"),
|
||||||
|
KLT_REPACK_M("Repacking KLT, HU >=15kg [EUR/HU]", "3,02 €"),
|
||||||
|
GLT_REPACK_S("Repacking GLT, HU <15kg [EUR/HU]", "3,02 €"),
|
||||||
|
GLT_REPACK_M("Repacking GLT, HU 15 - 2000kg [EUR/HU]", "7,76 €"),
|
||||||
|
GLT_REPACK_L("Repacking GLT, HU > 2000kg [EUR/HU]", "14,00 €"),
|
||||||
|
DISPOSAL("GLT disposal [EUR/GLT]", "6,00 €"),
|
||||||
|
|
||||||
|
|
||||||
|
SPACE_COST("Space costs / m3 per night [EUR/m3]", "0,26 €"),
|
||||||
|
|
||||||
|
|
||||||
|
UNION("Customs Union", ""),
|
||||||
|
SAFTY_STOCK("Safety Stock [working days]", "30"),
|
||||||
|
AIR_SHARE("Air freight share [%]", "2"),
|
||||||
|
WAGE("Wage factor [%]", "100%");
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
private final String defaultValue;
|
||||||
|
|
||||||
|
|
||||||
|
SystemPropertyMappingId(String description, String defaultValue) {
|
||||||
|
this.description = description;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getDefaultValue() {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDefaultAsInteger() {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(defaultValue);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -59,7 +59,9 @@ public class NodeRepository {
|
||||||
return predecessors;
|
return predecessors;
|
||||||
}, id);
|
}, id);
|
||||||
}, id);
|
}, id);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
private Collection<Integer> getOutboundCountriesOf(Integer id) {
|
private Collection<Integer> getOutboundCountriesOf(Integer id) {
|
||||||
String query = """
|
String query = """
|
||||||
|
|
@ -107,7 +109,7 @@ public class NodeRepository {
|
||||||
private String buildQuery(String filter, Boolean excludeDeprecated, SearchQueryPagination searchQueryPagination) {
|
private String buildQuery(String filter, Boolean excludeDeprecated, SearchQueryPagination searchQueryPagination) {
|
||||||
StringBuilder queryBuilder = new StringBuilder("""
|
StringBuilder queryBuilder = new StringBuilder("""
|
||||||
SELECT node.id AS id, node.name AS name, node.address as address, node.is_source as is_source,
|
SELECT node.id AS id, node.name AS name, node.address as address, node.is_source as is_source,
|
||||||
node.is_sink as is_sink, node.is_intermediate as is_intermediate, node.country_id as country_id, node.predecessor_required as predecessor_required,
|
node.is_destination as is_destination, node.is_intermediate as is_intermediate, node.country_id as country_id, node.predecessor_required as predecessor_required,
|
||||||
country.iso_code AS country_iso_code, country.region_code AS country_region_code, country.name AS country_name, country.is_deprecated AS country_is_deprecated
|
country.iso_code AS country_iso_code, country.region_code AS country_region_code, country.name AS country_name, country.is_deprecated AS country_is_deprecated
|
||||||
FROM node
|
FROM node
|
||||||
LEFT JOIN country ON country.id = node.country_id
|
LEFT JOIN country ON country.id = node.country_id
|
||||||
|
|
@ -182,6 +184,91 @@ public class NodeRepository {
|
||||||
return Optional.ofNullable(node);
|
return Optional.ofNullable(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves chains of predecessors for a specified destination node by its ID.
|
||||||
|
* If the destination node does not require predecessors, an empty list is returned.
|
||||||
|
* Otherwise, it constructs a list of chains, where each chain represents a sequence of predecessor nodes.
|
||||||
|
*
|
||||||
|
* @param destinationId The ID of the destination node whose predecessor chains need to be resolved.
|
||||||
|
* Must not be null and must correspond to an existing node.
|
||||||
|
* @return A list of chains, where each chain is a list of nodes.
|
||||||
|
* Each list represents a sequence of predecessor nodes for the given destination node.
|
||||||
|
* If the destination node does not require predecessors, a list containing an empty list is returned.
|
||||||
|
* @throws RuntimeException If a predecessor node is not found for a given sequence number in the chain.
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public List<List<Node>> resolveChainsById(Integer destinationId) {
|
||||||
|
List<List<Node>> resolvedChains = new ArrayList<>();
|
||||||
|
|
||||||
|
Node destination = getById(destinationId).orElseThrow();
|
||||||
|
|
||||||
|
if (!destination.getPredecessorRequired())
|
||||||
|
resolvedChains.add(Collections.emptyList());
|
||||||
|
|
||||||
|
List<Map<Integer, Integer>> chains = destination.getNodePredecessors();
|
||||||
|
|
||||||
|
chains.forEach(chain -> {
|
||||||
|
|
||||||
|
var currentChain = new ArrayList<Node>();
|
||||||
|
resolvedChains.add(currentChain);
|
||||||
|
|
||||||
|
chain.keySet().forEach(sequenceNumber -> {
|
||||||
|
var predecessor = getById(chain.get(sequenceNumber));
|
||||||
|
if (predecessor.isEmpty()) {
|
||||||
|
throw new RuntimeException("Predecessor not found for chain " + chain + " and sequence number " + sequenceNumber);
|
||||||
|
}
|
||||||
|
currentChain.add(sequenceNumber, predecessor.get());
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return resolvedChains;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Node> getByDistance(Node node, Integer regionRadius) {
|
||||||
|
|
||||||
|
String query = """
|
||||||
|
SELECT * FROM node
|
||||||
|
WHERE is_deprecated = FALSE AND
|
||||||
|
(
|
||||||
|
6371 * acos(
|
||||||
|
cos(radians(?)) *
|
||||||
|
cos(radians(geo_lat)) *
|
||||||
|
cos(radians(geo_lng) - radians(?)) +
|
||||||
|
sin(radians(?)) *
|
||||||
|
sin(radians(geo_lat))
|
||||||
|
)
|
||||||
|
) <= ?
|
||||||
|
""";
|
||||||
|
|
||||||
|
return jdbcTemplate.query(query, new NodeMapper(), node.getGeoLat(), node.getGeoLng(), node.getGeoLat());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of nodes that are outbound from a given country.
|
||||||
|
* The method considers nodes that are either explicitly mapped to the given country
|
||||||
|
* or are intermediate nodes within the same country.
|
||||||
|
*
|
||||||
|
* @param countryId The ID of the country for which outbound nodes are to be retrieved.
|
||||||
|
* Must not be null.
|
||||||
|
* @return A list of nodes that are outbound for the specified country.
|
||||||
|
* Returns an empty list if no outbound nodes are found.
|
||||||
|
*/
|
||||||
|
public List<Node> getAllOutboundFor(Integer countryId) {
|
||||||
|
String query = """
|
||||||
|
SELECT node.id AS id, node.name AS name, node.address as address, node.is_source as is_source,
|
||||||
|
node.is_destination as is_destination, node.is_intermediate as is_intermediate, node.country_id as country_id, node.predecessor_required as predecessor_required
|
||||||
|
FROM node
|
||||||
|
LEFT JOIN outbound_country_mapping ON outbound_country_mapping.node_id = node.id
|
||||||
|
WHERE node.is_deprecated = FALSE AND (outbound_country_mapping.country_id = ? OR (node.is_intermediate = TRUE AND node.country_id = ?))
|
||||||
|
""";
|
||||||
|
|
||||||
|
return jdbcTemplate.query(query, new NodeMapper(), countryId);
|
||||||
|
}
|
||||||
|
|
||||||
private class NodeMapper implements RowMapper<Node> {
|
private class NodeMapper implements RowMapper<Node> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
package de.avatic.lcc.repositories.packaging;
|
package de.avatic.lcc.repositories.packaging;
|
||||||
|
|
||||||
|
import com.azure.spring.cloud.core.implementation.properties.PropertyMapper;
|
||||||
import de.avatic.lcc.model.properties.PackagingProperty;
|
import de.avatic.lcc.model.properties.PackagingProperty;
|
||||||
import de.avatic.lcc.model.properties.PropertyDataType;
|
import de.avatic.lcc.model.properties.PropertyDataType;
|
||||||
import de.avatic.lcc.model.properties.PropertyType;
|
import de.avatic.lcc.model.properties.PropertyType;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public class PackagingPropertiesRepository {
|
public class PackagingPropertiesRepository {
|
||||||
|
|
@ -25,8 +30,30 @@ public class PackagingPropertiesRepository {
|
||||||
type.external_mapping_id AS type_external_mapping_id, type.validation_rule AS type_validation_rule
|
type.external_mapping_id AS type_external_mapping_id, type.validation_rule AS type_validation_rule
|
||||||
FROM packaging_property property LEFT JOIN packaging_property_type type ON property.packaging_property_type_id = type.id WHERE packaging_id = ?""";
|
FROM packaging_property property LEFT JOIN packaging_property_type type ON property.packaging_property_type_id = type.id WHERE packaging_id = ?""";
|
||||||
|
|
||||||
return jdbcTemplate.query(query, (rs, rowNum) -> {
|
return jdbcTemplate.query(query, new PropertyMapper(), id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<PackagingProperty> getByPackagingIdAndType(Integer id, String type) {
|
||||||
|
String query = """
|
||||||
|
SELECT property.id as id, property.property_value AS value, property.packaging_id as packaging_id,
|
||||||
|
type.name AS type_name, type.data_type AS type_data_type, type.is_required AS type_is_required,
|
||||||
|
type.external_mapping_id AS type_external_mapping_id, type.validation_rule AS type_validation_rule
|
||||||
|
FROM packaging_property property LEFT JOIN packaging_property_type type ON property.packaging_property_type_id = type.id WHERE packaging_id = ? AND type.external_mapping_id = ?""";
|
||||||
|
|
||||||
|
var property = jdbcTemplate.query(query, new PropertyMapper(), id, type);
|
||||||
|
|
||||||
|
if(property.isEmpty())
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
return Optional.of(property.getFirst());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class PropertyMapper implements RowMapper<PackagingProperty> {
|
||||||
|
@Override
|
||||||
|
public PackagingProperty mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
PackagingProperty property = new PackagingProperty();
|
PackagingProperty property = new PackagingProperty();
|
||||||
PropertyType type = new PropertyType();
|
PropertyType type = new PropertyType();
|
||||||
|
|
||||||
|
|
@ -43,12 +70,10 @@ public class PackagingPropertiesRepository {
|
||||||
property.setValue(rs.getString("value"));
|
property.setValue(rs.getString("value"));
|
||||||
|
|
||||||
return property;
|
return property;
|
||||||
}, id);
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public List<PropertyType> listTypes() {
|
public List<PropertyType> listTypes() {
|
||||||
String query = """
|
String query = """
|
||||||
SELECT * FROM packaging_property_type
|
SELECT * FROM packaging_property_type
|
||||||
|
|
|
||||||
|
|
@ -180,4 +180,13 @@ public class PackagingRepository {
|
||||||
|
|
||||||
return jdbcTemplate.query(query, new PackagingMapper(), materialId);
|
return jdbcTemplate.query(query, new PackagingMapper(), materialId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Packaging> getByMaterialIdAndSupplierId(Integer materialId, Integer supplierId) {
|
||||||
|
String query = """
|
||||||
|
SELECT id, supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated
|
||||||
|
FROM packaging
|
||||||
|
WHERE packaging.material_id = ? AND packaging.supplier_node_id = ?""";
|
||||||
|
|
||||||
|
return jdbcTemplate.query(query, new PackagingMapper(), materialId, supplierId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package de.avatic.lcc.repositories.premise;
|
||||||
import de.avatic.lcc.model.premises.route.Destination;
|
import de.avatic.lcc.model.premises.route.Destination;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
|
@ -17,7 +18,7 @@ public class DestinationRepository {
|
||||||
|
|
||||||
public DestinationRepository(JdbcTemplate jdbcTemplate) {
|
public DestinationRepository(JdbcTemplate jdbcTemplate) {
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Destination> getById(Integer id) {
|
public Optional<Destination> getById(Integer id) {
|
||||||
String query = "SELECT * FROM premise_destination WHERE id = ?";
|
String query = "SELECT * FROM premise_destination WHERE id = ?";
|
||||||
|
|
@ -37,6 +38,39 @@ public class DestinationRepository {
|
||||||
return jdbcTemplate.query(query, new DestinationMapper(), id);
|
return jdbcTemplate.query(query, new DestinationMapper(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void deleteById(Integer id) {
|
||||||
|
if (id == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String sql = "DELETE FROM premise_destination WHERE id = ?";
|
||||||
|
jdbcTemplate.update(sql, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getOwnerIdById(Integer id) {
|
||||||
|
String query = """
|
||||||
|
SELECT p.user_id AS user_id
|
||||||
|
FROM premise_destination pd
|
||||||
|
JOIN premise p ON pd.premise_id = p.id
|
||||||
|
WHERE pd.id = ?""";
|
||||||
|
|
||||||
|
List<Integer> userId = jdbcTemplate.query(query, (rs, rowNum) -> {
|
||||||
|
return rs.getInt("userId");
|
||||||
|
}, id);
|
||||||
|
|
||||||
|
if (userId.isEmpty())
|
||||||
|
return Optional.empty();
|
||||||
|
else
|
||||||
|
return Optional.of(userId.getFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class DestinationMapper implements RowMapper<Destination> {
|
private static class DestinationMapper implements RowMapper<Destination> {
|
||||||
@Override
|
@Override
|
||||||
public Destination mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public Destination mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
|
@ -25,89 +27,87 @@ import java.util.Optional;
|
||||||
public class PremiseRepository {
|
public class PremiseRepository {
|
||||||
|
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
|
||||||
|
|
||||||
public PremiseRepository(JdbcTemplate jdbcTemplate) {
|
public PremiseRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
|
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchQueryResult<PremiseListEntry> listPremises(String filter, SearchQueryPagination pagination, Integer userId, Boolean deleted, Boolean archived, Boolean done) {
|
public SearchQueryResult<PremiseListEntry> listPremises(String filter, SearchQueryPagination pagination,
|
||||||
String query = buildQuery(filter, deleted, archived, done);
|
Integer userId, Boolean deleted, Boolean archived, Boolean done) {
|
||||||
String countQuery = buildCountQuery(filter, deleted, archived, done);
|
|
||||||
|
|
||||||
List<PremiseListEntry> entities = null;
|
QueryBuilder queryBuilder = new QueryBuilder()
|
||||||
Integer totalCount = 0;
|
.withFilter(filter)
|
||||||
|
.withDeleted(deleted)
|
||||||
|
.withArchived(archived)
|
||||||
|
.withDone(done);
|
||||||
|
|
||||||
if (filter == null || filter.isBlank()) {
|
String query = queryBuilder.buildSelectQuery();
|
||||||
entities = jdbcTemplate.query(query, new PremiseListEntryMapper(), userId, pagination.getLimit(), pagination.getOffset());
|
String countQuery = queryBuilder.buildCountQuery();
|
||||||
totalCount = jdbcTemplate.queryForObject(countQuery, Integer.class, userId);
|
|
||||||
|
List<PremiseListEntry> entities;
|
||||||
|
Integer totalCount;
|
||||||
|
|
||||||
|
if (isEmptyFilter(filter)) {
|
||||||
|
entities = executeQueryWithoutFilter(query, userId, pagination);
|
||||||
|
totalCount = executeCountQueryWithoutFilter(countQuery, userId);
|
||||||
} else {
|
} else {
|
||||||
entities = jdbcTemplate.query(query, new PremiseListEntryMapper(), userId, "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", pagination.getLimit(), pagination.getOffset());
|
entities = executeQueryWithFilter(query, userId, filter, pagination);
|
||||||
totalCount = jdbcTemplate.queryForObject(countQuery, Integer.class, userId, "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%", "%" + filter + "%");
|
totalCount = executeCountQueryWithFilter(countQuery, userId, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SearchQueryResult<>(entities, pagination.getPage(), totalCount, pagination.getLimit());
|
return new SearchQueryResult<>(entities, pagination.getPage(), totalCount, pagination.getLimit());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildCountQuery(String filter, Boolean deleted, Boolean archived, Boolean done) {
|
|
||||||
StringBuilder queryBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
queryBuilder.append("""
|
private boolean isEmptyFilter(String filter) {
|
||||||
SELECT COUNT(*) FROM premise AS p
|
return filter == null || filter.isBlank();
|
||||||
LEFT JOIN material as m ON p.material_id = m.id
|
|
||||||
LEFT JOIN node as n ON p.supplier_node_id = n.id
|
|
||||||
LEFT JOIN sys_user_node as user_n ON p.user_supplier_node_id = user_n.id
|
|
||||||
WHERE p.userId = ?""");
|
|
||||||
|
|
||||||
if (filter != null && !filter.isBlank()) {
|
|
||||||
queryBuilder.append(" AND (n.name LIKE ? OR n.external_mapping_id LIKE ? OR n.note LIKE ? OR user_n.name LIKE ? OR m.name LIKE ? OR m.description LIKE ? OR m.part_number LIKE ?)");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deleted != null && deleted) {
|
|
||||||
queryBuilder.append(" AND p.deleted = TRUE");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (archived != null && archived) {
|
|
||||||
queryBuilder.append(" AND p.archived = TRUE");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (done != null && done) {
|
|
||||||
queryBuilder.append(" AND p.done = TRUE");
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryBuilder.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<PremiseListEntry> executeQueryWithoutFilter(String query, Integer userId,
|
||||||
|
SearchQueryPagination pagination) {
|
||||||
|
return jdbcTemplate.query(
|
||||||
|
query,
|
||||||
|
new PremiseListEntryMapper(),
|
||||||
|
userId,
|
||||||
|
pagination.getLimit(),
|
||||||
|
pagination.getOffset()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private String buildQuery(String filter, Boolean deleted, Boolean archived, Boolean done) {
|
private Integer executeCountQueryWithoutFilter(String countQuery, Integer userId) {
|
||||||
|
return jdbcTemplate.queryForObject(countQuery, Integer.class, userId);
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder queryBuilder = new StringBuilder();
|
private List<PremiseListEntry> executeQueryWithFilter(String query, Integer userId,
|
||||||
|
String filter, SearchQueryPagination pagination) {
|
||||||
|
String wildcardFilter = "%" + filter + "%";
|
||||||
|
Object[] params = createFilterParams(userId, wildcardFilter, pagination);
|
||||||
|
return jdbcTemplate.query(query, new PremiseListEntryMapper(), params);
|
||||||
|
}
|
||||||
|
|
||||||
queryBuilder.append("""
|
private Integer executeCountQueryWithFilter(String countQuery, Integer userId, String filter) {
|
||||||
SELECT * FROM premise AS p
|
String wildcardFilter = "%" + filter + "%";
|
||||||
LEFT JOIN material as m ON p.material_id = m.id
|
Object[] params = createFilterParamsForCount(userId, wildcardFilter);
|
||||||
LEFT JOIN node as n ON p.supplier_node_id = n.id
|
return jdbcTemplate.queryForObject(countQuery, Integer.class, params);
|
||||||
LEFT JOIN sys_user_node as user_n ON p.user_supplier_node_id = user_n.id
|
}
|
||||||
WHERE p.userId = ?""");
|
|
||||||
|
|
||||||
if (filter != null && !filter.isBlank()) {
|
private Object[] createFilterParams(Integer userId, String wildcardFilter, SearchQueryPagination pagination) {
|
||||||
queryBuilder.append(" AND (n.name LIKE ? OR n.external_mapping_id LIKE ? OR n.note LIKE ? OR user_n.name LIKE ? OR m.name LIKE ? OR m.description LIKE ? OR m.part_number LIKE ?)");
|
return new Object[]{
|
||||||
}
|
userId,
|
||||||
if (deleted != null && deleted) {
|
wildcardFilter, wildcardFilter, wildcardFilter, wildcardFilter,
|
||||||
queryBuilder.append(" AND p.deleted = TRUE");
|
wildcardFilter, wildcardFilter, wildcardFilter,
|
||||||
}
|
pagination.getLimit(), pagination.getOffset()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (archived != null && archived) {
|
private Object[] createFilterParamsForCount(Integer userId, String wildcardFilter) {
|
||||||
queryBuilder.append(" AND p.archived = TRUE");
|
return new Object[]{
|
||||||
}
|
userId,
|
||||||
|
wildcardFilter, wildcardFilter, wildcardFilter, wildcardFilter,
|
||||||
if (done != null && done) {
|
wildcardFilter, wildcardFilter, wildcardFilter
|
||||||
queryBuilder.append(" AND p.done = TRUE");
|
};
|
||||||
}
|
|
||||||
|
|
||||||
queryBuilder.append(" LIMIT ? OFFSET ?");
|
|
||||||
queryBuilder.append(" ORDER BY p.updated_at DESC");
|
|
||||||
|
|
||||||
return queryBuilder.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -148,53 +148,48 @@ public class PremiseRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void updatePackaging(List<Integer> premiseIds, Integer userId, PackagingDimension dimensionEntity, Boolean stackable, Boolean mixable) {
|
public void updatePackaging(List<Integer> premiseIds, Integer userId, PackagingDimension dimensionEntity, Boolean stackable, Boolean mixable) {
|
||||||
|
|
||||||
String placeholders = String.join(",", Collections.nCopies(premiseIds.size(), "?"));
|
if (premiseIds == null || premiseIds.isEmpty() || userId == null || dimensionEntity == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String query = """
|
boolean isStackable = stackable != null ? stackable : false;
|
||||||
|
boolean isMixable = mixable != null ? mixable : false;
|
||||||
|
|
||||||
|
MapSqlParameterSource params = new MapSqlParameterSource();
|
||||||
|
params.addValue("length", dimensionEntity.getLength());
|
||||||
|
params.addValue("height", dimensionEntity.getHeight());
|
||||||
|
params.addValue("width", dimensionEntity.getWidth());
|
||||||
|
params.addValue("weight", dimensionEntity.getWeight());
|
||||||
|
params.addValue("dimensionUnit", dimensionEntity.getDimensionUnit().name());
|
||||||
|
params.addValue("weightUnit", dimensionEntity.getWeightUnit().name());
|
||||||
|
params.addValue("unitCount", dimensionEntity.getContentUnitCount());
|
||||||
|
params.addValue("stackable", isStackable);
|
||||||
|
params.addValue("mixable", isMixable);
|
||||||
|
params.addValue("userId", userId);
|
||||||
|
params.addValue("premiseIds", premiseIds);
|
||||||
|
|
||||||
|
String sql = """
|
||||||
UPDATE premise
|
UPDATE premise
|
||||||
SET individual_hu_length = ?,
|
SET individual_hu_length = :length,
|
||||||
individual_hu_height = ?,
|
individual_hu_height = :height,
|
||||||
individual_hu_width = ?,
|
individual_hu_width = :width,
|
||||||
individual_hu_weight = ?,
|
individual_hu_weight = :weight,
|
||||||
hu_displayed_dimension_unit = ?,
|
hu_displayed_dimension_unit = :dimensionUnit,
|
||||||
hu_displayed_weight_unit = ?,
|
hu_displayed_weight_unit = :weightUnit,
|
||||||
hu_unit_count = ?,
|
hu_unit_count = :unitCount,
|
||||||
hu_stackable = ?,
|
hu_stackable = :stackable,
|
||||||
hu_mixable = ?,
|
hu_mixable = :mixable
|
||||||
WHERE user_id = ? AND id IN (""" + placeholders + ")" ;
|
WHERE user_id = :userId AND id IN (:premiseIds)
|
||||||
|
""";
|
||||||
jdbcTemplate.update(
|
|
||||||
query,
|
|
||||||
ps -> {
|
|
||||||
ps.setInt(1, dimensionEntity.getLength());
|
|
||||||
ps.setInt(2, dimensionEntity.getHeight());
|
|
||||||
ps.setInt(3, dimensionEntity.getWidth());
|
|
||||||
ps.setInt(4, dimensionEntity.getWeight());
|
|
||||||
ps.setString(5, dimensionEntity.getDimensionUnit().name());
|
|
||||||
ps.setString(6, dimensionEntity.getWeightUnit().name());
|
|
||||||
ps.setInt(7, dimensionEntity.getContentUnitCount());
|
|
||||||
|
|
||||||
ps.setBoolean(8, stackable);
|
|
||||||
ps.setBoolean(9, mixable);
|
|
||||||
ps.setInt(10, userId);
|
|
||||||
|
|
||||||
for (int parameterIndex = 0; parameterIndex <= premiseIds.size(); parameterIndex++) {
|
|
||||||
ps.setInt(parameterIndex+10, premiseIds.get(parameterIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
namedParameterJdbcTemplate.update(sql, params);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateMaterial(List<Integer> premiseIds, Integer userId, String hsCode, BigDecimal tariffRate) {
|
public void updateMaterial(List<Integer> premiseIds, Integer userId, String hsCode, BigDecimal tariffRate) {
|
||||||
|
|
||||||
String placeholders = String.join(",", Collections.nCopies(premiseIds.size(), "?"));
|
String placeholders = String.join(",", Collections.nCopies(premiseIds.size(), "?"));
|
||||||
|
|
||||||
|
|
@ -202,7 +197,7 @@ public class PremiseRepository {
|
||||||
UPDATE premise
|
UPDATE premise
|
||||||
SET hs_code = ?,
|
SET hs_code = ?,
|
||||||
tariff_rate = ?
|
tariff_rate = ?
|
||||||
WHERE user_id = ? id IN ("""+placeholders+")";
|
WHERE user_id = ? AND id IN (""" + placeholders + ")";
|
||||||
|
|
||||||
jdbcTemplate.update(
|
jdbcTemplate.update(
|
||||||
query,
|
query,
|
||||||
|
|
@ -212,8 +207,8 @@ public class PremiseRepository {
|
||||||
ps.setBigDecimal(2, tariffRate);
|
ps.setBigDecimal(2, tariffRate);
|
||||||
ps.setInt(3, userId);
|
ps.setInt(3, userId);
|
||||||
|
|
||||||
for (int parameterIndex = 0; parameterIndex <= premiseIds.size(); parameterIndex++) {
|
for (int parameterIndex = 0; parameterIndex < premiseIds.size(); parameterIndex++) {
|
||||||
ps.setInt(parameterIndex+3, premiseIds.get(parameterIndex));
|
ps.setInt(parameterIndex + 4, premiseIds.get(parameterIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -227,7 +222,7 @@ public class PremiseRepository {
|
||||||
SET price = ?,
|
SET price = ?,
|
||||||
is_fca_enabled = ?,
|
is_fca_enabled = ?,
|
||||||
oversea_share = ?
|
oversea_share = ?
|
||||||
WHERE user_id = ? AND id IN ("""+placeholders+")";
|
WHERE user_id = ? AND id IN (""" + placeholders + ")";
|
||||||
|
|
||||||
jdbcTemplate.update(
|
jdbcTemplate.update(
|
||||||
query,
|
query,
|
||||||
|
|
@ -238,61 +233,171 @@ public class PremiseRepository {
|
||||||
ps.setBigDecimal(3, overseaShare);
|
ps.setBigDecimal(3, overseaShare);
|
||||||
ps.setInt(4, userId);
|
ps.setInt(4, userId);
|
||||||
|
|
||||||
for (int parameterIndex = 0; parameterIndex <= premiseIds.size(); parameterIndex++) {
|
for (int parameterIndex = 0; parameterIndex < premiseIds.size(); parameterIndex++) {
|
||||||
ps.setInt(parameterIndex+4, premiseIds.get(parameterIndex));
|
ps.setInt(parameterIndex + 6, premiseIds.get(parameterIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all draft premises that would conflict with updating the material or supplier for a given premise.
|
||||||
|
* <p>
|
||||||
|
* A conflict arises when multiple premises share the same combination of material ID and supplier ID while
|
||||||
|
* being in the DRAFT state. This method enables the identification of such potential duplicates, excluding
|
||||||
|
* the premise being evaluated to avoid self-collision.
|
||||||
|
*
|
||||||
|
* @param userId The ID of the user who owns the premises.
|
||||||
|
* @param premiseId The ID of the premise being checked; this premise will be excluded from the results.
|
||||||
|
* @param materialId The material ID to verify for potential conflicts.
|
||||||
|
* @param supplierId The supplier node ID to verify for potential conflicts.
|
||||||
|
* @return A list of premises in the DRAFT state with the same material and supplier combination (excluding the specified premise).
|
||||||
|
* @throws IllegalArgumentException If any of the provided parameters are null.
|
||||||
|
*/
|
||||||
|
public List<Premise> getCollidingPremisesOnChange(Integer userId, Integer premiseId, Integer materialId, Integer supplierId) {
|
||||||
|
|
||||||
|
if( premiseId == null || materialId == null || supplierId == null )
|
||||||
|
return Collections.emptyList();
|
||||||
|
|
||||||
|
String sql = "SELECT * FROM premise " +
|
||||||
|
"WHERE material_id = ? " +
|
||||||
|
"AND supplier_node_id = ? " +
|
||||||
|
"AND id != ? " +
|
||||||
|
"AND user_id = ? " +
|
||||||
|
"AND state = 'DRAFT'";
|
||||||
|
|
||||||
|
return jdbcTemplate.query(sql, new PremiseMapper(), materialId, supplierId, premiseId, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deletePremisesById(List<Integer> premiseIds) {
|
||||||
|
if(premiseIds == null || premiseIds.isEmpty()) return;
|
||||||
|
|
||||||
|
String placeholders = String.join(",", Collections.nCopies(premiseIds.size(), "?"));
|
||||||
|
String query = """
|
||||||
|
DELETE FROM premise
|
||||||
|
WHERE id IN (""" + placeholders + ") AND state = " + PremiseState.DRAFT.name();
|
||||||
|
|
||||||
|
jdbcTemplate.update(query, premiseIds.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateTariffRate(Integer premiseId, Number tariffRate) {
|
||||||
|
String sql = "UPDATE premise SET tariff_rate = ? WHERE id = ?";
|
||||||
|
|
||||||
|
jdbcTemplate.update(sql, tariffRate, premiseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupplierId(List<Integer> premiseId, Integer supplierId, boolean userSupplierNode) {
|
||||||
|
String placeholders = String.join(",", Collections.nCopies(premiseId.size(), "?"));
|
||||||
|
String sql = "UPDATE premise SET supplier_node_id = ?, user_supplier_node_id = ? WHERE id IN ("+placeholders+")";
|
||||||
|
|
||||||
|
if(userSupplierNode) {
|
||||||
|
jdbcTemplate.update(sql, 0, supplierId, premiseId.toArray());
|
||||||
|
} else {
|
||||||
|
jdbcTemplate.update(sql, supplierId, 0, premiseId.toArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates SQL query building logic
|
||||||
|
*/
|
||||||
|
private static class QueryBuilder {
|
||||||
|
private static final String BASE_JOIN_QUERY = """
|
||||||
|
FROM premise AS p
|
||||||
|
LEFT JOIN material as m ON p.material_id = m.id
|
||||||
|
LEFT JOIN node as n ON p.supplier_node_id = n.id
|
||||||
|
LEFT JOIN sys_user_node as user_n ON p.user_supplier_node_id = user_n.id
|
||||||
|
WHERE p.userId = ?""";
|
||||||
|
|
||||||
|
private static final String FILTER_CONDITION =
|
||||||
|
" AND (n.name LIKE ? OR n.external_mapping_id LIKE ? OR n.note LIKE ? OR " +
|
||||||
|
"user_n.name LIKE ? OR m.name LIKE ? OR m.description LIKE ? OR m.part_number LIKE ?)";
|
||||||
|
|
||||||
|
private String filter;
|
||||||
|
private Boolean deleted;
|
||||||
|
private Boolean archived;
|
||||||
|
private Boolean done;
|
||||||
|
|
||||||
|
public QueryBuilder withFilter(String filter) {
|
||||||
|
this.filter = filter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryBuilder withDeleted(Boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryBuilder withArchived(Boolean archived) {
|
||||||
|
this.archived = archived;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryBuilder withDone(Boolean done) {
|
||||||
|
this.done = done;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String buildCountQuery() {
|
||||||
|
StringBuilder queryBuilder = new StringBuilder();
|
||||||
|
queryBuilder.append("SELECT COUNT(*) ").append(BASE_JOIN_QUERY);
|
||||||
|
appendConditions(queryBuilder);
|
||||||
|
return queryBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String buildSelectQuery() {
|
||||||
|
StringBuilder queryBuilder = new StringBuilder();
|
||||||
|
queryBuilder.append("SELECT * ").append(BASE_JOIN_QUERY);
|
||||||
|
appendConditions(queryBuilder);
|
||||||
|
queryBuilder.append(" ORDER BY p.updated_at DESC");
|
||||||
|
queryBuilder.append(" LIMIT ? OFFSET ?");
|
||||||
|
return queryBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendConditions(StringBuilder queryBuilder) {
|
||||||
|
if (filter != null && !filter.isBlank()) {
|
||||||
|
queryBuilder.append(FILTER_CONDITION);
|
||||||
|
}
|
||||||
|
|
||||||
|
appendBooleanCondition(queryBuilder, deleted, "p.deleted");
|
||||||
|
appendBooleanCondition(queryBuilder, archived, "p.archived");
|
||||||
|
appendBooleanCondition(queryBuilder, done, "p.done");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendBooleanCondition(StringBuilder queryBuilder, Boolean condition, String field) {
|
||||||
|
if (condition != null && condition) {
|
||||||
|
queryBuilder.append(" AND ").append(field).append(" = TRUE");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class PremiseListEntryMapper implements RowMapper<PremiseListEntry> {
|
private static class PremiseListEntryMapper implements RowMapper<PremiseListEntry> {
|
||||||
@Override
|
@Override
|
||||||
public PremiseListEntry mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public PremiseListEntry mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
|
||||||
PremiseListEntry entity = new PremiseListEntry();
|
PremiseListEntry entity = new PremiseListEntry();
|
||||||
|
|
||||||
entity.setId(rs.getInt("p.id"));
|
// Map base premise properties
|
||||||
entity.setState(de.avatic.lcc.dto.calculation.PremiseState.valueOf(rs.getString("p.state")));
|
mapBasePremiseProperties(entity, rs);
|
||||||
entity.setOwnerId(rs.getInt("p.user_id"));
|
|
||||||
entity.setCreatedAt(rs.getTimestamp("p.created_at").toLocalDateTime());
|
|
||||||
entity.setUpdatedAt(rs.getTimestamp("p.created_at").toLocalDateTime());
|
|
||||||
|
|
||||||
|
// Map material
|
||||||
entity.setMaterial(mapMaterial(rs));
|
entity.setMaterial(mapMaterial(rs));
|
||||||
|
|
||||||
if (rs.getInt("p.supplier_node_id") != 0) {
|
// Map supplier (either regular node or user node)
|
||||||
entity.setSupplierId(rs.getInt("n.id"));
|
mapSupplierProperties(entity, rs);
|
||||||
entity.setSupplierName(rs.getString("n.name"));
|
|
||||||
entity.setSupplierAddress(rs.getString("n.address"));
|
|
||||||
entity.setSupplierCountryId(rs.getInt("n.country_id"));
|
|
||||||
entity.setUserSupplier(false);
|
|
||||||
|
|
||||||
entity.setSupplierGeoLatitude(rs.getBigDecimal("n.geo_latitude"));
|
|
||||||
entity.setSupplierGeoLongitude(rs.getBigDecimal("n.geo_longitude"));
|
|
||||||
|
|
||||||
entity.setSupplierIsDestination(rs.getBoolean("n.is_destination"));
|
|
||||||
entity.setSupplierIsIntermediate(rs.getBoolean("n.is_intermediate"));
|
|
||||||
entity.setSupplierIsSource(rs.getBoolean("n.is_source"));
|
|
||||||
|
|
||||||
} else if (rs.getInt("p.user_supplier_node_id") != 0) {
|
|
||||||
entity.setSupplierId(rs.getInt("user_n.id"));
|
|
||||||
entity.setSupplierName(rs.getString("user_n.name"));
|
|
||||||
entity.setSupplierAddress(rs.getString("user_n.address"));
|
|
||||||
entity.setSupplierCountryId(rs.getInt("user_n.country_id"));
|
|
||||||
entity.setUserSupplier(false);
|
|
||||||
|
|
||||||
entity.setSupplierGeoLatitude(rs.getBigDecimal("user_n.geo_latitude"));
|
|
||||||
entity.setSupplierGeoLongitude(rs.getBigDecimal("user_n.geo_longitude"));
|
|
||||||
|
|
||||||
entity.setSupplierIsDestination(rs.getBoolean("user_n.is_destination"));
|
|
||||||
entity.setSupplierIsIntermediate(rs.getBoolean("user_n.is_intermediate"));
|
|
||||||
entity.setSupplierIsSource(rs.getBoolean("user_n.is_source"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mapBasePremiseProperties(PremiseListEntry entity, ResultSet rs) throws SQLException {
|
||||||
|
entity.setId(rs.getInt("p.id"));
|
||||||
|
entity.setState(de.avatic.lcc.dto.calculation.PremiseState.valueOf(rs.getString("p.state")));
|
||||||
|
entity.setOwnerId(rs.getInt("p.user_id"));
|
||||||
|
entity.setCreatedAt(rs.getTimestamp("p.created_at").toLocalDateTime());
|
||||||
|
entity.setUpdatedAt(rs.getTimestamp("p.created_at").toLocalDateTime()); // Note: This looks like a bug, should be "p.updated_at"
|
||||||
|
}
|
||||||
|
|
||||||
private Material mapMaterial(ResultSet rs) throws SQLException {
|
private Material mapMaterial(ResultSet rs) throws SQLException {
|
||||||
var data = new Material();
|
Material data = new Material();
|
||||||
|
|
||||||
data.setId(rs.getInt("m.id"));
|
data.setId(rs.getInt("m.id"));
|
||||||
data.setName(rs.getString("m.name"));
|
data.setName(rs.getString("m.name"));
|
||||||
|
|
@ -302,6 +407,29 @@ public class PremiseRepository {
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mapSupplierProperties(PremiseListEntry entity, ResultSet rs) throws SQLException {
|
||||||
|
if (rs.getInt("p.supplier_node_id") != 0) {
|
||||||
|
mapSupplier(entity, rs, "n");
|
||||||
|
} else if (rs.getInt("p.user_supplier_node_id") != 0) {
|
||||||
|
mapSupplier(entity, rs, "user_n");
|
||||||
|
entity.setUserSupplier(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mapSupplier(PremiseListEntry entity, ResultSet rs, String tablePrefix) throws SQLException {
|
||||||
|
entity.setSupplierId(rs.getInt(tablePrefix + ".id"));
|
||||||
|
entity.setSupplierName(rs.getString(tablePrefix + ".name"));
|
||||||
|
entity.setSupplierAddress(rs.getString(tablePrefix + ".address"));
|
||||||
|
entity.setSupplierCountryId(rs.getInt(tablePrefix + ".country_id"));
|
||||||
|
|
||||||
|
entity.setSupplierGeoLatitude(rs.getBigDecimal(tablePrefix + ".geo_latitude"));
|
||||||
|
entity.setSupplierGeoLongitude(rs.getBigDecimal(tablePrefix + ".geo_longitude"));
|
||||||
|
|
||||||
|
entity.setSupplierIsDestination(rs.getBoolean(tablePrefix + ".is_destination"));
|
||||||
|
entity.setSupplierIsIntermediate(rs.getBoolean(tablePrefix + ".is_intermediate"));
|
||||||
|
entity.setSupplierIsSource(rs.getBoolean(tablePrefix + ".is_source"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class PremiseMapper implements RowMapper<Premise> {
|
private static class PremiseMapper implements RowMapper<Premise> {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
@ -31,6 +32,17 @@ public class RouteNodeRepository {
|
||||||
return Optional.of(nodes.getFirst());
|
return Optional.of(nodes.getFirst());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteAllById(List<Integer> ids) {
|
||||||
|
if (ids == null || ids.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String placeholders = String.join(",", Collections.nCopies(ids.size(), "?"));
|
||||||
|
String sql = "DELETE FROM premise_route_node WHERE id IN (" + placeholders + ")";
|
||||||
|
|
||||||
|
jdbcTemplate.update(sql, ids.toArray(new Object[0]));
|
||||||
|
}
|
||||||
|
|
||||||
private static class RouteNodeMapper implements RowMapper<RouteNode> {
|
private static class RouteNodeMapper implements RowMapper<RouteNode> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
|
|
@ -23,6 +24,18 @@ public class RouteRepository {
|
||||||
return jdbcTemplate.query(query, new RouteMapper(), id);
|
return jdbcTemplate.query(query, new RouteMapper(), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteAllById(List<Integer> ids) {
|
||||||
|
if (ids == null || ids.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a parameterized SQL statement with placeholders for each ID
|
||||||
|
String placeholders = String.join(",", Collections.nCopies(ids.size(), "?"));
|
||||||
|
String sql = "DELETE FROM premise_route WHERE id IN (" + placeholders + ")";
|
||||||
|
|
||||||
|
jdbcTemplate.update(sql, ids.toArray(new Object[0]));
|
||||||
|
}
|
||||||
|
|
||||||
private static class RouteMapper implements RowMapper<Route> {
|
private static class RouteMapper implements RowMapper<Route> {
|
||||||
@Override
|
@Override
|
||||||
public Route mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public Route mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ package de.avatic.lcc.repositories.premise;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.generic.RouteType;
|
import de.avatic.lcc.dto.generic.RouteType;
|
||||||
import de.avatic.lcc.model.premises.route.RouteSection;
|
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||||
import de.avatic.lcc.model.premises.route.RouteSectionType;
|
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
|
|
@ -27,6 +27,17 @@ public class RouteSectionRepository {
|
||||||
return jdbcTemplate.query(query, new RouteSectionMapper(), routeId);
|
return jdbcTemplate.query(query, new RouteSectionMapper(), routeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteAllById(List<Integer> ids) {
|
||||||
|
if (ids == null || ids.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String placeholders = String.join(",", Collections.nCopies(ids.size(), "?"));
|
||||||
|
String sql = "DELETE FROM premise_route_section WHERE id IN (" + placeholders + ")";
|
||||||
|
|
||||||
|
jdbcTemplate.update(sql, ids.toArray(new Object[0]));
|
||||||
|
}
|
||||||
|
|
||||||
private static class RouteSectionMapper implements RowMapper<RouteSection> {
|
private static class RouteSectionMapper implements RowMapper<RouteSection> {
|
||||||
@Override
|
@Override
|
||||||
public RouteSection mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public RouteSection mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package de.avatic.lcc.repositories.properties;
|
package de.avatic.lcc.repositories.properties;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.generic.PropertyDTO;
|
import de.avatic.lcc.dto.generic.PropertyDTO;
|
||||||
|
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||||
import de.avatic.lcc.model.rates.ValidityPeriodState;
|
import de.avatic.lcc.model.rates.ValidityPeriodState;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
|
@ -10,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -96,26 +98,25 @@ public class PropertyRepository {
|
||||||
WHERE propertySet.state = ? AND propertySet.id = ?
|
WHERE propertySet.state = ? AND propertySet.id = ?
|
||||||
""";
|
""";
|
||||||
|
|
||||||
return jdbcTemplate.query(query, new PropertyMapper(),ValidityPeriodState.EXPIRED.name(), propertySetId);
|
return jdbcTemplate.query(query, new PropertyMapper(), ValidityPeriodState.EXPIRED.name(), propertySetId);
|
||||||
}
|
|
||||||
|
|
||||||
private static class PropertyMapper implements RowMapper<PropertyDTO> {
|
|
||||||
@Override
|
|
||||||
public PropertyDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
|
|
||||||
var dto = new PropertyDTO();
|
|
||||||
|
|
||||||
dto.setName(rs.getString("name"));
|
|
||||||
dto.setDraftValue(rs.getString("draftValue"));
|
|
||||||
dto.setCurrentValue(rs.getString("validValue"));
|
|
||||||
dto.setValidationRule(rs.getString("validationRule"));
|
|
||||||
dto.setExternalMappingId(rs.getString("externalMappingId"));
|
|
||||||
dto.setRequired(true);
|
|
||||||
dto.setDataType(rs.getString("dataType"));
|
|
||||||
|
|
||||||
return dto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<PropertyDTO> getPropertyByMappingId(SystemPropertyMappingId mappingId) {
|
||||||
|
String query = """
|
||||||
|
SELECT type.name as name, type.data_type as dataType, type.external_mapping_id as externalMappingId, type.validation_rule as validationRule,
|
||||||
|
property.property_value as draftValue, property.property_value as validValue
|
||||||
|
FROM system_property_type AS type
|
||||||
|
LEFT JOIN system_property AS property ON property.system_property_type_id = type.id
|
||||||
|
LEFT JOIN property_set AS propertySet ON propertySet.id = property.property_set_id
|
||||||
|
WHERE propertySet.state = ? AND type.external_mapping_id = ?
|
||||||
|
""";
|
||||||
|
|
||||||
|
var property = jdbcTemplate.query(query, new PropertyMapper(), ValidityPeriodState.VALID.name(), mappingId.name());
|
||||||
|
|
||||||
|
if (property.isEmpty()) return Optional.empty();
|
||||||
|
else return Optional.of(property.getFirst());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills the draft property set with values from a valid property set.
|
* Fills the draft property set with values from a valid property set.
|
||||||
|
|
@ -137,4 +138,21 @@ public class PropertyRepository {
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class PropertyMapper implements RowMapper<PropertyDTO> {
|
||||||
|
@Override
|
||||||
|
public PropertyDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
|
var dto = new PropertyDTO();
|
||||||
|
|
||||||
|
dto.setName(rs.getString("name"));
|
||||||
|
dto.setDraftValue(rs.getString("draftValue"));
|
||||||
|
dto.setCurrentValue(rs.getString("validValue"));
|
||||||
|
dto.setValidationRule(rs.getString("validationRule"));
|
||||||
|
dto.setExternalMappingId(rs.getString("externalMappingId"));
|
||||||
|
dto.setRequired(true);
|
||||||
|
dto.setDataType(rs.getString("dataType"));
|
||||||
|
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository for managing {@link MatrixRate} entities, including retrieval and mapping of MatrixRate rows
|
* Repository for managing {@link MatrixRate} entities, including retrieval and mapping of MatrixRate rows
|
||||||
|
|
@ -76,6 +77,16 @@ public class MatrixRateRepository {
|
||||||
return jdbcTemplate.query(query, new MatrixRateMapper());
|
return jdbcTemplate.query(query, new MatrixRateMapper());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<MatrixRate> getByCountryIds(Integer fromCountryId, Integer toCountryId) {
|
||||||
|
String query = "SELECT * FROM country_matrix_rate WHERE from_country_id = ? AND to_country_id = ?";
|
||||||
|
var rates = jdbcTemplate.query(query, new MatrixRateMapper(), fromCountryId, toCountryId);
|
||||||
|
|
||||||
|
if(rates.isEmpty())
|
||||||
|
return Optional.empty();
|
||||||
|
else
|
||||||
|
return Optional.of(rates.getFirst());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps rows of a {@link ResultSet} to {@link MatrixRate} objects as required by
|
* Maps rows of a {@link ResultSet} to {@link MatrixRate} objects as required by
|
||||||
* the {@link JdbcTemplate}.
|
* the {@link JdbcTemplate}.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.calculation;
|
package de.avatic.lcc.service;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.configuration;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.configuration.rates.ContainerRateDTO;
|
import de.avatic.lcc.dto.configuration.rates.ContainerRateDTO;
|
||||||
import de.avatic.lcc.dto.generic.ContainerType;
|
import de.avatic.lcc.dto.generic.ContainerType;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.configuration;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.configuration.countries.view.CountryDetailDTO;
|
import de.avatic.lcc.dto.configuration.countries.view.CountryDetailDTO;
|
||||||
import de.avatic.lcc.dto.generic.CountryDTO;
|
import de.avatic.lcc.dto.generic.CountryDTO;
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
|
import de.avatic.lcc.dto.calculation.edit.destination.DestinationCreateDTO;
|
||||||
|
import de.avatic.lcc.dto.calculation.DestinationDTO;
|
||||||
|
import de.avatic.lcc.dto.calculation.edit.destination.DestinationUpdateDTO;
|
||||||
|
import de.avatic.lcc.model.premises.route.Route;
|
||||||
|
import de.avatic.lcc.model.premises.route.RouteSection;
|
||||||
|
import de.avatic.lcc.repositories.premise.DestinationRepository;
|
||||||
|
import de.avatic.lcc.repositories.premise.RouteNodeRepository;
|
||||||
|
import de.avatic.lcc.repositories.premise.RouteRepository;
|
||||||
|
import de.avatic.lcc.repositories.premise.RouteSectionRepository;
|
||||||
|
import de.avatic.lcc.service.transformer.premise.DestinationTransformer;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class DestinationService {
|
||||||
|
|
||||||
|
|
||||||
|
private final DestinationRepository destinationRepository;
|
||||||
|
private final DestinationTransformer destinationTransformer;
|
||||||
|
private final RouteRepository routeRepository;
|
||||||
|
private final RouteSectionRepository routeSectionRepository;
|
||||||
|
private final RouteNodeRepository routeNodeRepository;
|
||||||
|
|
||||||
|
public DestinationService(DestinationRepository destinationRepository, DestinationTransformer destinationTransformer, RouteRepository routeRepository, RouteSectionRepository routeSectionRepository, RouteNodeRepository routeNodeRepository) {
|
||||||
|
this.destinationRepository = destinationRepository;
|
||||||
|
this.destinationTransformer = destinationTransformer;
|
||||||
|
this.routeRepository = routeRepository;
|
||||||
|
this.routeSectionRepository = routeSectionRepository;
|
||||||
|
this.routeNodeRepository = routeNodeRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<Integer, DestinationDTO> createDestination(DestinationCreateDTO destinationCreateDTO) {
|
||||||
|
|
||||||
|
// do some checks
|
||||||
|
// - no duplicates
|
||||||
|
|
||||||
|
// do routing.
|
||||||
|
|
||||||
|
// create database entries.
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DestinationDTO getDestination(Integer id) {
|
||||||
|
//todo check authorization
|
||||||
|
|
||||||
|
return destinationTransformer.toDestinationDTO(destinationRepository.getById(id).orElseThrow());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateDestination(Integer id, DestinationUpdateDTO destinationUpdateDTO) {
|
||||||
|
|
||||||
|
//todo check authorization
|
||||||
|
Integer userId = 1;
|
||||||
|
|
||||||
|
destinationRepository.update(id, userId, destinationUpdateDTO.getRepackingCost(), destinationUpdateDTO.getDisposalCost(), destinationUpdateDTO.getHandlingCost());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllDestinationsByPremiseId(List<Integer> ids, boolean deleteRoutesOnly) {
|
||||||
|
ids.forEach(id -> deleteDestinationById(id, deleteRoutesOnly));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteDestinationById(Integer id, boolean deleteRoutesOnly) {
|
||||||
|
//todo check authorization
|
||||||
|
Integer userId = 1;
|
||||||
|
Optional<Integer> ownerId = destinationRepository.getOwnerIdById(id);
|
||||||
|
|
||||||
|
if(ownerId.isPresent() && ownerId.get().equals(userId)) {
|
||||||
|
List<Route> routes = routeRepository.getByDestinationId(id);
|
||||||
|
|
||||||
|
for(var route : routes) {
|
||||||
|
List<RouteSection> sections = routeSectionRepository.getByRouteId(route.getId());
|
||||||
|
routeSectionRepository.deleteAllById(sections.stream().map(RouteSection::getId).toList());
|
||||||
|
routeNodeRepository.deleteAllById(sections.stream().flatMap(section -> Stream.of(section.getFromRouteNodeId(), section.getToRouteNodeId())).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
routeRepository.deleteAllById(routes.stream().map(Route::getId).toList());
|
||||||
|
|
||||||
|
if(!deleteRoutesOnly)
|
||||||
|
destinationRepository.deleteById(id);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("Not authorized to delete destination with id " + id);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package de.avatic.lcc.service.configuration;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.configuration.material.update.MaterialUpdateDTO;
|
|
||||||
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
import de.avatic.lcc.dto.configuration.material.view.MaterialDetailDTO;
|
||||||
import de.avatic.lcc.dto.generic.MaterialDTO;
|
import de.avatic.lcc.dto.generic.MaterialDTO;
|
||||||
import de.avatic.lcc.model.materials.Material;
|
import de.avatic.lcc.model.materials.Material;
|
||||||
|
|
@ -8,7 +7,6 @@ import de.avatic.lcc.repositories.MaterialRepository;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.service.transformer.generic.MaterialTransformer;
|
import de.avatic.lcc.service.transformer.generic.MaterialTransformer;
|
||||||
import de.avatic.lcc.service.transformer.material.MaterialUpdateDTOTransformer;
|
|
||||||
import de.avatic.lcc.service.transformer.material.MaterialDetailTransformer;
|
import de.avatic.lcc.service.transformer.material.MaterialDetailTransformer;
|
||||||
import de.avatic.lcc.util.exception.clienterror.MaterialNotFoundException;
|
import de.avatic.lcc.util.exception.clienterror.MaterialNotFoundException;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.configuration;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.configuration.matrixrates.MatrixRateDTO;
|
import de.avatic.lcc.dto.configuration.matrixrates.MatrixRateDTO;
|
||||||
import de.avatic.lcc.model.rates.MatrixRate;
|
import de.avatic.lcc.model.rates.MatrixRate;
|
||||||
|
|
@ -20,7 +20,7 @@ import java.util.Optional;
|
||||||
* business logic for matrix rates.
|
* business logic for matrix rates.
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class MatrixRateService {
|
public class MatrixRateService {
|
||||||
|
|
||||||
private final ValidityPeriodRepository validityPeriodRepository;
|
private final ValidityPeriodRepository validityPeriodRepository;
|
||||||
private final MatrixRateRepository matrixRateRepository;
|
private final MatrixRateRepository matrixRateRepository;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.configuration;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.configuration.nodes.userNodes.AddUserNodeDTO;
|
import de.avatic.lcc.dto.configuration.nodes.userNodes.AddUserNodeDTO;
|
||||||
import de.avatic.lcc.dto.generic.NodeDTO;
|
import de.avatic.lcc.dto.generic.NodeDTO;
|
||||||
|
|
@ -12,7 +12,6 @@ import de.avatic.lcc.repositories.country.CountryRepository;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
import de.avatic.lcc.repositories.users.UserNodeRepository;
|
import de.avatic.lcc.repositories.users.UserNodeRepository;
|
||||||
import de.avatic.lcc.service.GeoApiService;
|
|
||||||
import de.avatic.lcc.service.transformer.nodes.NodeUpdateDTOTransformer;
|
import de.avatic.lcc.service.transformer.nodes.NodeUpdateDTOTransformer;
|
||||||
import de.avatic.lcc.service.transformer.nodes.NodeDetailTransformer;
|
import de.avatic.lcc.service.transformer.nodes.NodeDetailTransformer;
|
||||||
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
|
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
|
||||||
|
|
@ -23,6 +22,10 @@ import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service class for managing lifecycle operations for nodes and related entities.
|
||||||
|
* Provides methods to list, retrieve, update, delete, and create nodes in the system.
|
||||||
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class NodeService {
|
public class NodeService {
|
||||||
|
|
||||||
|
|
@ -43,26 +46,72 @@ public class NodeService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated list of nodes filtered by the provided keyword.
|
||||||
|
*
|
||||||
|
* @param filter the filter keyword to search nodes.
|
||||||
|
* @param page the page number to retrieve.
|
||||||
|
* @param limit the number of nodes per page.
|
||||||
|
* @return a {@link SearchQueryResult} containing the paginated list of nodes.
|
||||||
|
*/
|
||||||
public SearchQueryResult<NodeDTO> listNodes(String filter, int page, int limit) {
|
public SearchQueryResult<NodeDTO> listNodes(String filter, int page, int limit) {
|
||||||
return SearchQueryResult.map(nodeRepository.listNodes(filter, true, new SearchQueryPagination(page, limit)), nodeTransformer::toNodeDTO);
|
return SearchQueryResult.map(nodeRepository.listNodes(filter, true, new SearchQueryPagination(page, limit)), nodeTransformer::toNodeDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a paginated detailed view of nodes based on the provided filter.
|
||||||
|
*
|
||||||
|
* @param filter the filter keyword to search nodes.
|
||||||
|
* @param page the page number to retrieve.
|
||||||
|
* @param limit the number of nodes per page.
|
||||||
|
* @return a {@link SearchQueryResult} containing detailed information of nodes.
|
||||||
|
*/
|
||||||
public SearchQueryResult<NodeDetailDTO> listNodesView(String filter, int page, int limit) {
|
public SearchQueryResult<NodeDetailDTO> listNodesView(String filter, int page, int limit) {
|
||||||
return SearchQueryResult.map(nodeRepository.listNodes(filter, true, new SearchQueryPagination(page, limit)), nodeDetailTransformer::toNodeDetailDTO);
|
return SearchQueryResult.map(nodeRepository.listNodes(filter, true, new SearchQueryPagination(page, limit)), nodeDetailTransformer::toNodeDetailDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the detailed view of a specific node by its ID.
|
||||||
|
*
|
||||||
|
* @param id the ID of the node to retrieve.
|
||||||
|
* @return a {@link NodeDetailDTO} containing detailed information of the node.
|
||||||
|
* @throws NodeNotFoundException if no node is found with the specified ID.
|
||||||
|
*/
|
||||||
public NodeDetailDTO getNode(Integer id) {
|
public NodeDetailDTO getNode(Integer id) {
|
||||||
return nodeDetailTransformer.toNodeDetailDTO(nodeRepository.getById(id).orElseThrow(() -> new NodeNotFoundException(id)));
|
return nodeDetailTransformer.toNodeDetailDTO(nodeRepository.getById(id).orElseThrow(() -> new NodeNotFoundException(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a node as deprecated by its ID.
|
||||||
|
*
|
||||||
|
* @param id the ID of the node to delete.
|
||||||
|
* @return the ID of the deprecated node.
|
||||||
|
* @throws NodeNotFoundException if no node is found with the specified ID.
|
||||||
|
*/
|
||||||
public Integer deleteNode(Integer id) {
|
public Integer deleteNode(Integer id) {
|
||||||
return nodeRepository.setDeprecatedById(id).orElseThrow(() -> new NodeNotFoundException(id));
|
return nodeRepository.setDeprecatedById(id).orElseThrow(() -> new NodeNotFoundException(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an existing node with the provided data.
|
||||||
|
*
|
||||||
|
* @param dto the {@link NodeUpdateDTO} containing the update data for the node.
|
||||||
|
* @return the ID of the updated node.
|
||||||
|
* @throws NodeNotFoundException if no node is found for the update.
|
||||||
|
*/
|
||||||
public Integer updateNode(NodeUpdateDTO dto) {
|
public Integer updateNode(NodeUpdateDTO dto) {
|
||||||
return nodeRepository.update(nodeUpdateDTOTransformer.fromNodeUpdateDTO(dto)).orElseThrow(() -> new NodeNotFoundException(dto.getId()));
|
return nodeRepository.update(nodeUpdateDTOTransformer.fromNodeUpdateDTO(dto)).orElseThrow(() -> new NodeNotFoundException(dto.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for nodes by filter and type with an option to include user-specific nodes.
|
||||||
|
*
|
||||||
|
* @param filter the filter keyword to search nodes.
|
||||||
|
* @param limit the maximum number of nodes to retrieve.
|
||||||
|
* @param nodeType the type of node to restrict the search to.
|
||||||
|
* @param includeUserNode if true, includes user-specific nodes in the search results.
|
||||||
|
* @return a list of {@link NodeDTO} objects representing the search results.
|
||||||
|
*/
|
||||||
public List<NodeDTO> searchNode(String filter, int limit, NodeType nodeType, boolean includeUserNode) {
|
public List<NodeDTO> searchNode(String filter, int limit, NodeType nodeType, boolean includeUserNode) {
|
||||||
List<NodeDTO> nodes = new ArrayList<>();
|
List<NodeDTO> nodes = new ArrayList<>();
|
||||||
int userId = 1; //TODO get current user's id
|
int userId = 1; //TODO get current user's id
|
||||||
|
|
@ -80,19 +129,5 @@ public class NodeService {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUserNode(AddUserNodeDTO dto) {
|
|
||||||
Node node = new Node();
|
|
||||||
|
|
||||||
node.setName(dto.getName());
|
|
||||||
node.setAddress(dto.getAddress());
|
|
||||||
node.setGeoLng(BigDecimal.valueOf(dto.getLocation().getLongitude()));
|
|
||||||
node.setGeoLat(BigDecimal.valueOf(dto.getLocation().getLatitude()));
|
|
||||||
node.setDestination(false);
|
|
||||||
node.setSource(true);
|
|
||||||
node.setIntermediate(false);
|
|
||||||
node.setDeprecated(false);
|
|
||||||
node.setCountryId(countryRepository.getByIsoCode(IsoCode.valueOf(dto.getCountry().getIsoCode())).orElseThrow().getId());
|
|
||||||
|
|
||||||
userNodeRepository.add(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
package de.avatic.lcc.service.calculation;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.calculation.PremiseDTO;
|
import de.avatic.lcc.dto.calculation.PremiseDTO;
|
||||||
import de.avatic.lcc.dto.calculation.edit.PremiseDetailDTO;
|
import de.avatic.lcc.dto.calculation.edit.PremiseDetailDTO;
|
||||||
import de.avatic.lcc.dto.calculation.edit.SetDataDTO;
|
import de.avatic.lcc.dto.calculation.edit.masterData.MaterialUpdateDTO;
|
||||||
import de.avatic.lcc.dto.calculation.edit.masterData.*;
|
import de.avatic.lcc.dto.calculation.edit.masterData.PackagingUpdateDTO;
|
||||||
import de.avatic.lcc.repositories.premise.PremiseRepository;
|
import de.avatic.lcc.dto.calculation.edit.masterData.PriceUpdateDTO;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||||
|
import de.avatic.lcc.repositories.premise.*;
|
||||||
import de.avatic.lcc.service.transformer.generic.DimensionTransformer;
|
import de.avatic.lcc.service.transformer.generic.DimensionTransformer;
|
||||||
import de.avatic.lcc.service.transformer.premise.PremiseTransformer;
|
import de.avatic.lcc.service.transformer.premise.PremiseTransformer;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
@ -15,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class PremisesService {
|
public class PremisesService {
|
||||||
|
|
@ -22,11 +24,13 @@ public class PremisesService {
|
||||||
private final PremiseRepository premiseRepository;
|
private final PremiseRepository premiseRepository;
|
||||||
private final PremiseTransformer premiseTransformer;
|
private final PremiseTransformer premiseTransformer;
|
||||||
private final DimensionTransformer dimensionTransformer;
|
private final DimensionTransformer dimensionTransformer;
|
||||||
|
private final DestinationService destinationService;
|
||||||
|
|
||||||
public PremisesService(PremiseRepository premiseRepository, PremiseTransformer premiseTransformer, DimensionTransformer dimensionTransformer) {
|
public PremisesService(PremiseRepository premiseRepository, PremiseTransformer premiseTransformer, DimensionTransformer dimensionTransformer, DestinationService destinationService, DestinationRepository destinationRepository, RouteRepository routeRepository, RouteSectionRepository routeSectionRepository, RouteNodeRepository routeNodeRepository, DestinationService destinationService) {
|
||||||
this.premiseRepository = premiseRepository;
|
this.premiseRepository = premiseRepository;
|
||||||
this.premiseTransformer = premiseTransformer;
|
this.premiseTransformer = premiseTransformer;
|
||||||
this.dimensionTransformer = dimensionTransformer;
|
this.dimensionTransformer = dimensionTransformer;
|
||||||
|
this.destinationService = destinationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
|
|
@ -39,7 +43,6 @@ public class PremisesService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public List<PremiseDetailDTO> getPremises(List<Integer> premiseIds) {
|
public List<PremiseDetailDTO> getPremises(List<Integer> premiseIds) {
|
||||||
//TODO check if user authorized
|
//TODO check if user authorized
|
||||||
|
|
@ -47,42 +50,12 @@ public class PremisesService {
|
||||||
return premiseRepository.getPremisesById(premiseIds).stream().map(premiseTransformer::toPremiseDetailDTO).toList();
|
return premiseRepository.getPremisesById(premiseIds).stream().map(premiseTransformer::toPremiseDetailDTO).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO move to other service
|
||||||
public Integer startCalculation(List<Integer> premises) {
|
public Integer startCalculation(List<Integer> premises) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<PremiseDetailDTO> setSupplier(SetDataDTO setSupplierDTO) {
|
|
||||||
//0. check if one of the given premises contains the same part number, and abort if any duplicate would emerge
|
|
||||||
|
|
||||||
//1. delete all routes.
|
|
||||||
|
|
||||||
//2. recalculate routes
|
|
||||||
|
|
||||||
//3 if updateMasterDate is set:
|
|
||||||
//3.1 copy packaging data (if exists) of new supplier to premise
|
|
||||||
//3.2 set new tariff rate (if supplier country changed)
|
|
||||||
|
|
||||||
//4. Deliver Premise Detail
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<PremiseDetailDTO> setMaterial(SetDataDTO setMaterialDTO) {
|
|
||||||
//0. check if one of the given premises contains the same supplier id, and abort if any duplicate would emerge
|
|
||||||
|
|
||||||
//3 if updateMasterDate is set:
|
|
||||||
//3.1 copy packaging data (if exists) of new material to premise
|
|
||||||
//3.2 set new tariff rate and hs code (if supplier country changed)
|
|
||||||
|
|
||||||
//4. Deliver Premise Detail
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<String, String> updatePackaging(PackagingUpdateDTO packagingDTO) {
|
public HashMap<String, String> updatePackaging(PackagingUpdateDTO packagingDTO) {
|
||||||
|
|
||||||
//TODO check values. and return errors if needed
|
//TODO check values. and return errors if needed
|
||||||
|
|
@ -111,7 +84,17 @@ public class PremisesService {
|
||||||
premiseRepository.updatePrice(priceUpdateDTO.getPremiseIds(), userId, BigDecimal.valueOf(priceUpdateDTO.getPrice().doubleValue()), priceUpdateDTO.getIncludeFcaFee(), BigDecimal.valueOf(priceUpdateDTO.getOverseaShare().doubleValue()));
|
premiseRepository.updatePrice(priceUpdateDTO.getPremiseIds(), userId, BigDecimal.valueOf(priceUpdateDTO.getPrice().doubleValue()), priceUpdateDTO.getIncludeFcaFee(), BigDecimal.valueOf(priceUpdateDTO.getOverseaShare().doubleValue()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void delete(List<Integer> premiseIds) {
|
||||||
|
//TODO check authorization
|
||||||
|
destinationService.deleteAllDestinationsByPremiseId(premiseIds, false);
|
||||||
|
premiseRepository.deletePremisesById(premiseIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fillPackaging(List<Integer> premiseIds) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.configuration;
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
||||||
import de.avatic.lcc.dto.generic.PropertyDTO;
|
import de.avatic.lcc.dto.generic.PropertyDTO;
|
||||||
|
|
@ -10,6 +10,20 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service for managing properties and property sets within the application.
|
||||||
|
* <p>
|
||||||
|
* This service provides functionality to:
|
||||||
|
* <ul>
|
||||||
|
* <li>Set property values for specific mappings</li>
|
||||||
|
* <li>List properties filtered by property set ID</li>
|
||||||
|
* <li>List all property sets with their validity periods</li>
|
||||||
|
* <li>Invalidate property sets</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* The service interacts with {@link PropertyRepository} and {@link PropertySetRepository}
|
||||||
|
* to perform CRUD operations on properties and property sets.
|
||||||
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class PropertyService {
|
public class PropertyService {
|
||||||
|
|
||||||
|
|
@ -21,8 +35,9 @@ public class PropertyService {
|
||||||
/**
|
/**
|
||||||
* Constructs the PropertyService with the provided repositories.
|
* Constructs the PropertyService with the provided repositories.
|
||||||
*
|
*
|
||||||
* @param propertyRepository the repository to manage properties
|
* @param propertyRepository the repository to manage properties
|
||||||
* @param propertySetRepository the repository to manage property sets
|
* @param propertySetRepository the repository to manage property sets
|
||||||
|
* @param validityPeriodTransformer the transformer to convert property sets to validity period DTOs
|
||||||
*/
|
*/
|
||||||
public PropertyService(PropertyRepository propertyRepository, PropertySetRepository propertySetRepository, ValidityPeriodTransformer validityPeriodTransformer) {
|
public PropertyService(PropertyRepository propertyRepository, PropertySetRepository propertySetRepository, ValidityPeriodTransformer validityPeriodTransformer) {
|
||||||
this.propertyRepository = propertyRepository;
|
this.propertyRepository = propertyRepository;
|
||||||
|
|
@ -32,6 +47,9 @@ public class PropertyService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a property value for a given mapping ID.
|
* Sets a property value for a given mapping ID.
|
||||||
|
* <p>
|
||||||
|
* This method updates the property value in the current draft set for the specified mapping ID.
|
||||||
|
* Note: Property value validation is pending implementation.
|
||||||
*
|
*
|
||||||
* @param mappingId the identifier of the property to be updated
|
* @param mappingId the identifier of the property to be updated
|
||||||
* @param value the new value to be set for the property
|
* @param value the new value to be set for the property
|
||||||
|
|
@ -45,12 +63,14 @@ public class PropertyService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a list of properties. If a specific property set ID is provided, only
|
* Retrieves a list of properties based on the specified property set ID.
|
||||||
* properties from that set are returned. Otherwise, the properties from the current
|
* <p>
|
||||||
* valid set and current draft set are returned.
|
* If the property set ID is 0, all properties from both the current valid set
|
||||||
|
* and current draft set are returned. Otherwise, only properties from the
|
||||||
|
* specified property set are returned.
|
||||||
*
|
*
|
||||||
* @param propertySetId the ID of the property set (0 for all properties)
|
* @param propertySetId the ID of the property set (0 for all properties)
|
||||||
* @return a list of properties as {@link PropertyDTO}
|
* @return a list of properties as {@link PropertyDTO} objects
|
||||||
*/
|
*/
|
||||||
public List<PropertyDTO> listProperties(Integer propertySetId) {
|
public List<PropertyDTO> listProperties(Integer propertySetId) {
|
||||||
if (propertySetId == 0)
|
if (propertySetId == 0)
|
||||||
|
|
@ -61,8 +81,11 @@ public class PropertyService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a list of all property sets, mapping them to validity period data transfer objects.
|
* Retrieves a list of all property sets, mapping them to validity period data transfer objects.
|
||||||
|
* <p>
|
||||||
|
* This method fetches all property sets from the repository and transforms each of them
|
||||||
|
* into a {@link ValidityPeriodDTO} using the injected transformer.
|
||||||
*
|
*
|
||||||
* @return a list of property sets as {@link ValidityPeriodDTO}
|
* @return a list of property sets as {@link ValidityPeriodDTO} objects
|
||||||
*/
|
*/
|
||||||
public List<ValidityPeriodDTO> listPropertySets() {
|
public List<ValidityPeriodDTO> listPropertySets() {
|
||||||
return propertySetRepository.listPropertySets().stream().map(validityPeriodTransformer::toValidityPeriodDTO).toList();
|
return propertySetRepository.listPropertySets().stream().map(validityPeriodTransformer::toValidityPeriodDTO).toList();
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
|
import de.avatic.lcc.dto.configuration.nodes.userNodes.AddUserNodeDTO;
|
||||||
|
import de.avatic.lcc.model.country.IsoCode;
|
||||||
|
import de.avatic.lcc.model.nodes.Node;
|
||||||
|
import de.avatic.lcc.repositories.country.CountryRepository;
|
||||||
|
import de.avatic.lcc.repositories.users.UserNodeRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserNodeService {
|
||||||
|
private final CountryRepository countryRepository;
|
||||||
|
private final UserNodeRepository userNodeRepository;
|
||||||
|
|
||||||
|
public UserNodeService(CountryRepository countryRepository, UserNodeRepository userNodeRepository) {
|
||||||
|
this.countryRepository = countryRepository;
|
||||||
|
this.userNodeRepository = userNodeRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getUserNode(Integer id) {
|
||||||
|
return userNodeRepository.getById(id).orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a user-specific node to the system based on the provided {@link AddUserNodeDTO}.
|
||||||
|
*
|
||||||
|
* @param dto the {@link AddUserNodeDTO} containing details about the user node to create, including name,
|
||||||
|
* address, geographic location, and country information.
|
||||||
|
* @throws IllegalArgumentException if any required information in the DTO is missing or invalid.
|
||||||
|
*/
|
||||||
|
public void addUserNode(AddUserNodeDTO dto) {
|
||||||
|
Node node = new Node();
|
||||||
|
|
||||||
|
node.setName(dto.getName());
|
||||||
|
node.setAddress(dto.getAddress());
|
||||||
|
node.setGeoLng(BigDecimal.valueOf(dto.getLocation().getLongitude()));
|
||||||
|
node.setGeoLat(BigDecimal.valueOf(dto.getLocation().getLatitude()));
|
||||||
|
node.setDestination(false);
|
||||||
|
node.setSource(true);
|
||||||
|
node.setIntermediate(false);
|
||||||
|
node.setDeprecated(false);
|
||||||
|
node.setCountryId(countryRepository.getByIsoCode(IsoCode.valueOf(dto.getCountry().getIsoCode())).orElseThrow().getId());
|
||||||
|
|
||||||
|
userNodeRepository.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
package de.avatic.lcc.service.access;
|
||||||
|
|
||||||
|
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
||||||
|
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
|
||||||
|
import de.avatic.lcc.service.transformer.rates.ValidityPeriodTransformer;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service class responsible for managing validity periods in the system.
|
||||||
|
* <p>
|
||||||
|
* This service provides operations for retrieving and manipulating validity periods,
|
||||||
|
* acting as an intermediary between the repository layer and the application layer.
|
||||||
|
* It uses a transformer to convert between entity and DTO representations.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ValidityPeriodService {
|
||||||
|
|
||||||
|
private final ValidityPeriodRepository validityPeriodRepository;
|
||||||
|
private final ValidityPeriodTransformer validityPeriodTransformer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ValidityPeriodService with the required dependencies.
|
||||||
|
*
|
||||||
|
* @param validityPeriodRepository Repository for accessing validity period data
|
||||||
|
* @param validityPeriodTransformer Transformer for converting between entity and DTO representations
|
||||||
|
*/
|
||||||
|
public ValidityPeriodService(ValidityPeriodRepository validityPeriodRepository, ValidityPeriodTransformer validityPeriodTransformer) {
|
||||||
|
this.validityPeriodRepository = validityPeriodRepository;
|
||||||
|
this.validityPeriodTransformer = validityPeriodTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all validity periods from the repository and transforms them to DTOs.
|
||||||
|
* <p>
|
||||||
|
* Fetches the list of validity periods from the repository and transforms each entity
|
||||||
|
* to its corresponding DTO representation using the transformer.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return A list of {@link ValidityPeriodDTO} objects representing all validity periods
|
||||||
|
*/
|
||||||
|
public List<ValidityPeriodDTO> listPeriods() {
|
||||||
|
return validityPeriodRepository.listPeriods().stream().map(validityPeriodTransformer::toValidityPeriodDTO).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates a validity period with the specified ID.
|
||||||
|
* <p>
|
||||||
|
* Marks the validity period as invalid in the repository based on its ID.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param id The unique identifier of the validity period to invalidate
|
||||||
|
*/
|
||||||
|
public void invalidate(Integer id) {
|
||||||
|
validityPeriodRepository.invalidateById(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import de.avatic.lcc.model.bulk.BulkFileTypes;
|
||||||
import de.avatic.lcc.model.bulk.HiddenTableType;
|
import de.avatic.lcc.model.bulk.HiddenTableType;
|
||||||
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
|
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
|
||||||
import de.avatic.lcc.service.bulk.helper.HeaderCellStyleProvider;
|
import de.avatic.lcc.service.bulk.helper.HeaderCellStyleProvider;
|
||||||
import de.avatic.lcc.service.bulk.mapper.*;
|
import de.avatic.lcc.service.excelMapper.*;
|
||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.usermodel.SheetVisibility;
|
import org.apache.poi.ss.usermodel.SheetVisibility;
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,7 @@ import de.avatic.lcc.dto.bulk.BulkFileType;
|
||||||
import de.avatic.lcc.dto.bulk.BulkProcessingType;
|
import de.avatic.lcc.dto.bulk.BulkProcessingType;
|
||||||
import de.avatic.lcc.dto.bulk.BulkStatus;
|
import de.avatic.lcc.dto.bulk.BulkStatus;
|
||||||
import de.avatic.lcc.model.bulk.BulkFileTypes;
|
import de.avatic.lcc.model.bulk.BulkFileTypes;
|
||||||
import de.avatic.lcc.model.materials.Material;
|
import de.avatic.lcc.service.excelMapper.*;
|
||||||
import de.avatic.lcc.model.rates.ContainerRate;
|
|
||||||
import de.avatic.lcc.model.rates.MatrixRate;
|
|
||||||
import de.avatic.lcc.service.bulk.mapper.*;
|
|
||||||
import de.avatic.lcc.util.exception.clienterror.FileFormatNotSupportedException;
|
import de.avatic.lcc.util.exception.clienterror.FileFormatNotSupportedException;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
|
@ -16,7 +13,6 @@ import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class BulkFileProcessingService {
|
public class BulkFileProcessingService {
|
||||||
|
|
@ -65,6 +61,7 @@ public class BulkFileProcessingService {
|
||||||
break;
|
break;
|
||||||
case NODE:
|
case NODE:
|
||||||
var nodes = nodeExcelMapper.extractSheet(sheet);
|
var nodes = nodeExcelMapper.extractSheet(sheet);
|
||||||
|
// check predecessors chains for loops or contradictions
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,8 @@ import de.avatic.lcc.dto.bulk.BulkFileType;
|
||||||
import de.avatic.lcc.model.bulk.*;
|
import de.avatic.lcc.model.bulk.*;
|
||||||
import de.avatic.lcc.service.bulk.helper.HeaderCellStyleProvider;
|
import de.avatic.lcc.service.bulk.helper.HeaderCellStyleProvider;
|
||||||
import de.avatic.lcc.service.bulk.helper.HeaderGenerator;
|
import de.avatic.lcc.service.bulk.helper.HeaderGenerator;
|
||||||
import de.avatic.lcc.service.bulk.mapper.*;
|
import de.avatic.lcc.service.excelMapper.*;
|
||||||
import org.apache.poi.ss.SpreadsheetVersion;
|
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.core.io.ByteArrayResource;
|
import org.springframework.core.io.ByteArrayResource;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package de.avatic.lcc.service.calculation;
|
||||||
|
|
||||||
|
import de.avatic.lcc.dto.calculation.edit.PremiseDetailDTO;
|
||||||
|
import de.avatic.lcc.dto.calculation.edit.SetDataDTO;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ChangeMaterialService {
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<PremiseDetailDTO> setMaterial(SetDataDTO setMaterialDTO) {
|
||||||
|
//0. check if one of the given premises contains the same supplier id, and abort if any duplicate would emerge
|
||||||
|
|
||||||
|
//3 if updateMasterDate is set:
|
||||||
|
//3.1 copy packaging data (if exists) of new material to premise
|
||||||
|
//3.2 set new tariff rate and hs code (if supplier country changed)
|
||||||
|
|
||||||
|
//4. Deliver Premise Detail
|
||||||
|
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
package de.avatic.lcc.service.calculation;
|
||||||
|
|
||||||
|
import de.avatic.lcc.dto.calculation.edit.PremiseDetailDTO;
|
||||||
|
import de.avatic.lcc.dto.calculation.edit.SetDataDTO;
|
||||||
|
import de.avatic.lcc.model.nodes.Node;
|
||||||
|
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.PackagingProperty;
|
||||||
|
import de.avatic.lcc.model.properties.PackagingPropertyMappingId;
|
||||||
|
import de.avatic.lcc.repositories.MaterialRepository;
|
||||||
|
import de.avatic.lcc.repositories.NodeRepository;
|
||||||
|
import de.avatic.lcc.repositories.packaging.PackagingDimensionRepository;
|
||||||
|
import de.avatic.lcc.repositories.packaging.PackagingPropertiesRepository;
|
||||||
|
import de.avatic.lcc.repositories.packaging.PackagingRepository;
|
||||||
|
import de.avatic.lcc.repositories.premise.DestinationRepository;
|
||||||
|
import de.avatic.lcc.repositories.premise.PremiseRepository;
|
||||||
|
import de.avatic.lcc.repositories.users.UserNodeRepository;
|
||||||
|
import de.avatic.lcc.service.CustomApiService;
|
||||||
|
import de.avatic.lcc.service.access.DestinationService;
|
||||||
|
import de.avatic.lcc.service.access.PremisesService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ChangeSupplierService {
|
||||||
|
|
||||||
|
private final PremiseRepository premiseRepository;
|
||||||
|
private final DestinationService destinationService;
|
||||||
|
private final RoutingService routingService;
|
||||||
|
private final PremisesService premisesService;
|
||||||
|
private final CustomApiService customApiService;
|
||||||
|
private final NodeRepository nodeRepository;
|
||||||
|
private final UserNodeRepository userNodeRepository;
|
||||||
|
private final MaterialRepository materialRepository;
|
||||||
|
private final PackagingRepository packagingRepository;
|
||||||
|
private final PackagingDimensionRepository packagingDimensionRepository;
|
||||||
|
private final PackagingPropertiesRepository packagingPropertiesRepository;
|
||||||
|
private final DestinationRepository destinationRepository;
|
||||||
|
|
||||||
|
public ChangeSupplierService(PremiseRepository premiseRepository, DestinationService destinationService, RoutingService routingService, PremisesService premisesService, CustomApiService customApiService, NodeRepository nodeRepository, UserNodeRepository userNodeRepository, MaterialRepository materialRepository, PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, PackagingPropertiesRepository packagingPropertiesRepository, DestinationRepository destinationRepository) {
|
||||||
|
this.premiseRepository = premiseRepository;
|
||||||
|
this.destinationService = destinationService;
|
||||||
|
this.routingService = routingService;
|
||||||
|
this.premisesService = premisesService;
|
||||||
|
this.customApiService = customApiService;
|
||||||
|
this.nodeRepository = nodeRepository;
|
||||||
|
this.userNodeRepository = userNodeRepository;
|
||||||
|
this.materialRepository = materialRepository;
|
||||||
|
this.packagingRepository = packagingRepository;
|
||||||
|
this.packagingDimensionRepository = packagingDimensionRepository;
|
||||||
|
this.packagingPropertiesRepository = packagingPropertiesRepository;
|
||||||
|
this.destinationRepository = destinationRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<PremiseDetailDTO> setSupplier(SetDataDTO dto) {
|
||||||
|
|
||||||
|
Integer userId = 1; // todo get current user;
|
||||||
|
Integer supplierNodeId = dto.getSupplierNodeId();
|
||||||
|
List<Integer> premiseIds = dto.getPremiseId();
|
||||||
|
|
||||||
|
if (supplierNodeId == null || premiseIds == null || premiseIds.isEmpty())
|
||||||
|
throw new IllegalArgumentException("No supplier supplierNodeId or premises given");
|
||||||
|
|
||||||
|
Node supplier = dto.isUserSupplierNode() ? userNodeRepository.getById(supplierNodeId).orElseThrow() : nodeRepository.getById(supplierNodeId).orElseThrow();
|
||||||
|
|
||||||
|
// get all premises first.
|
||||||
|
List<Premise> allPremises = premiseRepository.getPremisesById(premiseIds);
|
||||||
|
|
||||||
|
// find resulting duplicates, split into "keep" and "to be deleted".
|
||||||
|
Map<Integer, Premise> uniqueMap = new HashMap<>();
|
||||||
|
List<Premise> premisesToBeDeleted = new ArrayList<>();
|
||||||
|
allPremises.forEach(p -> {
|
||||||
|
if (null != uniqueMap.putIfAbsent(p.getMaterialId(), p)) premisesToBeDeleted.add(p);
|
||||||
|
});
|
||||||
|
Collection<Premise> premisesToProcess = uniqueMap.values();
|
||||||
|
|
||||||
|
// check if user owns all premises:
|
||||||
|
if (allPremises.stream().anyMatch(p -> !p.getUserId().equals(userId)))
|
||||||
|
throw new IllegalArgumentException("Not authorized to change suppliers of premises owned by other users");
|
||||||
|
|
||||||
|
// check for any other collisions, and mark as "to be deleted":
|
||||||
|
premisesToBeDeleted.addAll(premisesToProcess.stream().map(p -> premiseRepository.getCollidingPremisesOnChange(userId, p.getId(), p.getMaterialId(), supplierNodeId)).flatMap(List::stream).toList());
|
||||||
|
|
||||||
|
// delete all routes of all destinations
|
||||||
|
destinationService.deleteAllDestinationsByPremiseId(premisesToProcess.stream().map(Premise::getId).toList(), true);
|
||||||
|
|
||||||
|
//recalculate routes:
|
||||||
|
for (Premise premise : premisesToProcess) {
|
||||||
|
List<Destination> destination = destinationRepository.getByPremiseId(premise.getId());
|
||||||
|
for( Destination d : destination ) {
|
||||||
|
routingService.findRoutes(d.getId(), supplierNodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//update master data:
|
||||||
|
if (dto.isUpdateMasterData()) {
|
||||||
|
for (var premise : premisesToProcess) {
|
||||||
|
var tariffRate = customApiService.getTariffRate(premise.getHsCode(), supplier.getCountryId());
|
||||||
|
premiseRepository.updateTariffRate(premise.getId(), tariffRate);
|
||||||
|
|
||||||
|
if (!dto.isUserSupplierNode()) {
|
||||||
|
var packaging = packagingRepository.getByMaterialIdAndSupplierId(premise.getMaterialId(), supplierNodeId);
|
||||||
|
Optional<PackagingDimension> dimension = packagingDimensionRepository.getById(packaging.getFirst().getHuId());
|
||||||
|
|
||||||
|
if (dimension.isPresent()) {
|
||||||
|
Optional<PackagingProperty> stackable = packagingPropertiesRepository.getByPackagingIdAndType(packaging.getFirst().getId(), PackagingPropertyMappingId.STACKABLE.name());
|
||||||
|
Optional<PackagingProperty> mixable = packagingPropertiesRepository.getByPackagingIdAndType(packaging.getFirst().getId(), PackagingPropertyMappingId.MIXABLE.name());
|
||||||
|
//TODO check optional
|
||||||
|
premiseRepository.updatePackaging(Collections.singletonList(premise.getId()), userId, dimension.get(), Boolean.valueOf(stackable.get().getValue()), Boolean.valueOf(mixable.get().getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
premisesService.fillPackaging(premisesToProcess.stream().map(Premise::getId).toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually update supplier supplierNodeId.
|
||||||
|
premiseRepository.setSupplierId(premisesToProcess.stream().map(Premise::getId).toList(), supplierNodeId, dto.isUserSupplierNode());
|
||||||
|
|
||||||
|
|
||||||
|
//delete all conflicting premises:
|
||||||
|
premisesService.delete(premisesToBeDeleted.stream().map(Premise::getId).toList());
|
||||||
|
|
||||||
|
|
||||||
|
return premisesService.getPremises(premisesToProcess.stream().map(Premise::getId).toList());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
package de.avatic.lcc.service.calculation;
|
|
||||||
|
|
||||||
import de.avatic.lcc.dto.calculation.edit.destination.DestinationCreateDTO;
|
|
||||||
import de.avatic.lcc.dto.calculation.DestinationDTO;
|
|
||||||
import de.avatic.lcc.dto.calculation.edit.destination.DestinationUpdateDTO;
|
|
||||||
import de.avatic.lcc.repositories.premise.DestinationRepository;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class DestinationService {
|
|
||||||
|
|
||||||
|
|
||||||
private final DestinationRepository destinationRepository;
|
|
||||||
|
|
||||||
public DestinationService(DestinationRepository destinationRepository) {
|
|
||||||
this.destinationRepository = destinationRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HashMap<Integer, DestinationDTO> createDestination(DestinationCreateDTO destinationCreateDTO) {
|
|
||||||
|
|
||||||
// do some checks
|
|
||||||
// - no duplicates
|
|
||||||
|
|
||||||
// do routing.
|
|
||||||
|
|
||||||
// create database entries.
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DestinationDTO getDestination(Integer id) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateDestination(Integer id, DestinationUpdateDTO destinationUpdateDTO) {
|
|
||||||
//destinationRepository.update(id, destinationUpdateDTO.)
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteDestination(Integer id) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
package de.avatic.lcc.service.calculation;
|
||||||
|
|
||||||
|
import de.avatic.lcc.model.nodes.Node;
|
||||||
|
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||||
|
import de.avatic.lcc.repositories.NodeRepository;
|
||||||
|
import de.avatic.lcc.repositories.country.CountryRepository;
|
||||||
|
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||||
|
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class RoutingService {
|
||||||
|
|
||||||
|
|
||||||
|
private final NodeRepository nodeRepository;
|
||||||
|
private final CountryRepository countryRepository;
|
||||||
|
private final MatrixRateRepository matrixRateRepository;
|
||||||
|
private final PropertyRepository propertyRepository;
|
||||||
|
|
||||||
|
public RoutingService(NodeRepository nodeRepository, CountryRepository countryRepository, MatrixRateRepository matrixRateRepository, PropertyRepository propertyRepository) {
|
||||||
|
this.nodeRepository = nodeRepository;
|
||||||
|
this.countryRepository = countryRepository;
|
||||||
|
this.matrixRateRepository = matrixRateRepository;
|
||||||
|
this.propertyRepository = propertyRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void findRoutes(Integer destinationId, Integer sourceId) {
|
||||||
|
var foundRoutes = new ArrayList<FoundRoute>();
|
||||||
|
|
||||||
|
Node source = nodeRepository.getById(sourceId).orElseThrow();
|
||||||
|
Node destination = nodeRepository.getById(destinationId).orElseThrow();
|
||||||
|
List<Node> regionNodes = nodeRepository.getByDistance(source, getRegionRadius());
|
||||||
|
List<Node> outboundNodes = nodeRepository.getAllOutboundFor(source.getCountryId());
|
||||||
|
|
||||||
|
List<List<Node>> destinationChains = resolveChains(destinationId);
|
||||||
|
Map<Integer, List<List<Node>>> outboundChains = getOutboundChains(outboundNodes);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foundRoutes.addAll(constructRoutesWithChains(destinationChains, source, destination));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Integer, List<List<Node>>> getOutboundChains(List<Node> outboundNodes) {
|
||||||
|
Map<Integer, List<List<Node>>> outboundChains = new HashMap<>();
|
||||||
|
for(var outboundNode : outboundNodes) {
|
||||||
|
outboundChains.put(outboundNode.getId(), resolveChains(outboundNode.getId()));
|
||||||
|
}
|
||||||
|
return outboundChains;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer getRegionRadius() {
|
||||||
|
var property = propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.RADIUS_REGION);
|
||||||
|
return property.map(propertyDTO -> Integer.valueOf(propertyDTO.getCurrentValue())).orElseGet(SystemPropertyMappingId.RADIUS_REGION::getDefaultAsInteger);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<FoundRoute> constructRoutesWithChains(List<List<Node>> chains, Node source, Node destination) {
|
||||||
|
ArrayList<FoundRoute> foundRoutes = new ArrayList<>();
|
||||||
|
|
||||||
|
for (var chain : chains) {
|
||||||
|
if(!chain.isEmpty()) {
|
||||||
|
var matrixRate = matrixRateRepository.getByCountryIds(chain.getLast().getCountryId(), source.getCountryId());
|
||||||
|
|
||||||
|
if(matrixRate.isPresent()) {
|
||||||
|
foundRoutes.add(new FoundRoute(chain, destination, source));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundRoutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves all possible chains of nodes starting from the specified node ID.
|
||||||
|
* This method recursively retrieves predecessor chains and appends successor chains
|
||||||
|
* to form complete resolution paths.
|
||||||
|
*
|
||||||
|
* @param nodeId The ID of the node from which the resolution process starts.
|
||||||
|
* Must not be null and must correspond to an existing node.
|
||||||
|
* @return A list of lists, where each inner list represents a fully resolved chain
|
||||||
|
* of nodes including predecessors and successors for the specified node ID.
|
||||||
|
*/
|
||||||
|
private List<List<Node>> resolveChains(Integer nodeId) {
|
||||||
|
var resolvedChains = new ArrayList<List<Node>>();
|
||||||
|
|
||||||
|
var predecessorChains = nodeRepository.resolveChainsById(nodeId);
|
||||||
|
|
||||||
|
for (var predecessorChain : predecessorChains) {
|
||||||
|
if (!predecessorChain.isEmpty()) {
|
||||||
|
var successorChains = resolveChains(predecessorChain.getLast().getId());
|
||||||
|
|
||||||
|
successorChains.forEach(successorChain -> {
|
||||||
|
successorChain.addAll(0, predecessorChain);
|
||||||
|
resolvedChains.add(successorChain);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolvedChains.add(predecessorChain);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolvedChains;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FoundRoute {
|
||||||
|
private List<Node> nodes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a FoundRoute object that represents a route consisting of a chain of nodes,
|
||||||
|
* starting with the source node, followed by the reversed chain of nodes, and ending with the destination node.
|
||||||
|
*
|
||||||
|
* @param chain The list of intermediary nodes in the route, in original order before reversing.
|
||||||
|
* Must not be null.
|
||||||
|
* @param destination The destination node in the route. Must not be null.
|
||||||
|
* @param source The source node in the route. Must not be null.
|
||||||
|
*/
|
||||||
|
public FoundRoute(List<Node> chain, Node destination, Node source) {
|
||||||
|
this.nodes = new ArrayList<>();
|
||||||
|
this.nodes.add(source);
|
||||||
|
this.nodes.addAll(chain.reversed());
|
||||||
|
this.nodes.add(destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package de.avatic.lcc.service.configuration;
|
|
||||||
|
|
||||||
import de.avatic.lcc.dto.generic.ValidityPeriodDTO;
|
|
||||||
import de.avatic.lcc.repositories.rates.ValidityPeriodRepository;
|
|
||||||
import de.avatic.lcc.service.transformer.rates.ValidityPeriodTransformer;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ValidityPeriodService {
|
|
||||||
|
|
||||||
private final ValidityPeriodRepository validityPeriodRepository;
|
|
||||||
private final ValidityPeriodTransformer validityPeriodTransformer;
|
|
||||||
|
|
||||||
public ValidityPeriodService(ValidityPeriodRepository validityPeriodRepository, ValidityPeriodTransformer validityPeriodTransformer) {
|
|
||||||
this.validityPeriodRepository = validityPeriodRepository;
|
|
||||||
this.validityPeriodTransformer = validityPeriodTransformer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ValidityPeriodDTO> listPeriods() {
|
|
||||||
return validityPeriodRepository.listPeriods().stream().map(validityPeriodTransformer::toValidityPeriodDTO).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void invalidate(Integer id) {
|
|
||||||
validityPeriodRepository.invalidateById(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.bulk.mapper;
|
package de.avatic.lcc.service.excelMapper;
|
||||||
|
|
||||||
import de.avatic.lcc.model.bulk.ContainerRateHeader;
|
import de.avatic.lcc.model.bulk.ContainerRateHeader;
|
||||||
import de.avatic.lcc.model.bulk.HiddenNodeHeader;
|
import de.avatic.lcc.model.bulk.HiddenNodeHeader;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.bulk.mapper;
|
package de.avatic.lcc.service.excelMapper;
|
||||||
|
|
||||||
import de.avatic.lcc.model.bulk.HiddenCountryHeader;
|
import de.avatic.lcc.model.bulk.HiddenCountryHeader;
|
||||||
import de.avatic.lcc.model.country.Country;
|
import de.avatic.lcc.model.country.Country;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.bulk.mapper;
|
package de.avatic.lcc.service.excelMapper;
|
||||||
|
|
||||||
import de.avatic.lcc.model.bulk.HiddenNodeHeader;
|
import de.avatic.lcc.model.bulk.HiddenNodeHeader;
|
||||||
import de.avatic.lcc.model.nodes.Node;
|
import de.avatic.lcc.model.nodes.Node;
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package de.avatic.lcc.service.bulk.mapper;
|
package de.avatic.lcc.service.excelMapper;
|
||||||
|
|
||||||
import de.avatic.lcc.model.bulk.ContainerRateHeader;
|
|
||||||
import de.avatic.lcc.model.bulk.MaterialHeader;
|
import de.avatic.lcc.model.bulk.MaterialHeader;
|
||||||
import de.avatic.lcc.model.materials.Material;
|
import de.avatic.lcc.model.materials.Material;
|
||||||
import de.avatic.lcc.repositories.MaterialRepository;
|
import de.avatic.lcc.repositories.MaterialRepository;
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
package de.avatic.lcc.service.bulk.mapper;
|
package de.avatic.lcc.service.excelMapper;
|
||||||
|
|
||||||
import de.avatic.lcc.model.bulk.*;
|
import de.avatic.lcc.model.bulk.*;
|
||||||
import de.avatic.lcc.model.country.IsoCode;
|
import de.avatic.lcc.model.country.IsoCode;
|
||||||
import de.avatic.lcc.model.rates.ContainerRateType;
|
|
||||||
import de.avatic.lcc.model.rates.MatrixRate;
|
import de.avatic.lcc.model.rates.MatrixRate;
|
||||||
import de.avatic.lcc.repositories.country.CountryRepository;
|
import de.avatic.lcc.repositories.country.CountryRepository;
|
||||||
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.bulk.mapper;
|
package de.avatic.lcc.service.excelMapper;
|
||||||
|
|
||||||
import de.avatic.lcc.excelmodel.ExcelNode;
|
import de.avatic.lcc.excelmodel.ExcelNode;
|
||||||
import de.avatic.lcc.model.bulk.HiddenCountryHeader;
|
import de.avatic.lcc.model.bulk.HiddenCountryHeader;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package de.avatic.lcc.service.bulk.mapper;
|
package de.avatic.lcc.service.excelMapper;
|
||||||
|
|
||||||
|
|
||||||
import de.avatic.lcc.excelmodel.ExcelPackaging;
|
import de.avatic.lcc.excelmodel.ExcelPackaging;
|
||||||
Loading…
Add table
Reference in a new issue