Refactor packaging-related classes and add new repository/service/controller.
Replaced `SearchQueryResult` utility class with a more robust `SearchQueryResult` under a new pagination package. Introduced `PackagingRepository` and `PackagingController` to manage packaging entities. Enhanced data models with new entities (`NodeType`, `PackagingDimension`), and updated existing ones (`Packaging`, `PackagingListEntry`) to improve modularity and support handling units.
This commit is contained in:
parent
6467a17cf8
commit
2b0ee0d417
18 changed files with 766 additions and 317 deletions
|
|
@ -2,7 +2,7 @@ package de.avatic.lcc.controller;
|
|||
|
||||
import de.avatic.lcc.model.materials.Material;
|
||||
import de.avatic.lcc.model.materials.MaterialListEntry;
|
||||
import de.avatic.lcc.repositories.utils.SearchQueryResult;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import de.avatic.lcc.service.MaterialService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
package de.avatic.lcc.controller;
|
||||
|
||||
import de.avatic.lcc.model.packaging.Packaging;
|
||||
import de.avatic.lcc.model.packaging.PackagingListEntry;
|
||||
import de.avatic.lcc.repositories.PackagingRepository;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import de.avatic.lcc.service.PackagingService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/packaging")
|
||||
public class PackagingController {
|
||||
|
||||
private final PackagingRepository packagingRepository;
|
||||
private final PackagingService packagingService;
|
||||
|
||||
@Autowired
|
||||
public PackagingController(PackagingRepository packagingRepository, PackagingService packagingService) {
|
||||
this.packagingRepository = packagingRepository;
|
||||
this.packagingService = packagingService;
|
||||
}
|
||||
|
||||
@GetMapping("/")
|
||||
public ResponseEntity<List<PackagingListEntry>> listPackaging(
|
||||
@RequestParam(defaultValue = "20") int limit,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(required = false) Integer materialId,
|
||||
@RequestParam(required = false) Integer supplierId) {
|
||||
|
||||
SearchQueryResult<PackagingListEntry> listEntries = packagingService.listPackaging(materialId, supplierId, page, limit);
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.header("X-Total-Count", String.valueOf(listEntries.getTotalElements()))
|
||||
.header("X-Page-Count", String.valueOf(listEntries.getTotalPages()))
|
||||
.header("X-Current-Page", String.valueOf(page))
|
||||
.body(listEntries.toList());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<Packaging> getPackagingDetails(@PathVariable Integer id) {
|
||||
return ResponseEntity.ok(packagingService.getPackaging(id));
|
||||
}
|
||||
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<Void> updatePackaging(@PathVariable Integer id, @RequestBody Packaging packaging) {
|
||||
packagingService.updatePackaging(id, packaging);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Integer> deletePackagingDetails(@PathVariable Integer id) {
|
||||
return ResponseEntity.ok(packagingService.deletePackaging(id));
|
||||
}
|
||||
|
||||
@PostMapping("/")
|
||||
public ResponseEntity<Integer> addPackaging(@RequestBody Packaging packaging) {
|
||||
return ResponseEntity.ok(packagingService.addPackaging(packaging));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -4,5 +4,24 @@ public class Location {
|
|||
private Double longitude;
|
||||
private Double latitude;
|
||||
|
||||
// Getters and setters
|
||||
public Location(Double longitude, Double latitude) {
|
||||
this.longitude = longitude;
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
public Double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLongitude(Double longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
public Double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setLatitude(Double latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ public class NodeListEntry {
|
|||
private String name;
|
||||
private CountryListEntry country;
|
||||
private String address;
|
||||
private Location location;
|
||||
private List<String> types;
|
||||
private List<NodeType> types;
|
||||
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -46,19 +45,11 @@ public class NodeListEntry {
|
|||
this.address = address;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(Location location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public List<String> getTypes() {
|
||||
public List<NodeType> getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(List<String> types) {
|
||||
public void setTypes(List<NodeType> types) {
|
||||
this.types = types;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
src/main/java/de/avatic/lcc/model/nodes/NodeType.java
Normal file
18
src/main/java/de/avatic/lcc/model/nodes/NodeType.java
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package de.avatic.lcc.model.nodes;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum NodeType {
|
||||
SINK("sink"), SOURCE("source"), INTERMEDIATE("intermediate");
|
||||
|
||||
private final String displayedType;
|
||||
|
||||
NodeType(String displayedType) {
|
||||
this.displayedType = displayedType;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getDisplayedType() {
|
||||
return displayedType;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,5 +12,44 @@ package de.avatic.lcc.model.packaging;
|
|||
* - MM: Millimeters
|
||||
*/
|
||||
public enum DimensionUnit {
|
||||
M, CM, MM
|
||||
M("m", 1000.0),
|
||||
CM("cm", 10.0),
|
||||
MM("mm", 1.0);
|
||||
|
||||
private final String displayedName;
|
||||
private final double baseFactor;
|
||||
|
||||
DimensionUnit(String displayedName, double baseFactor) {
|
||||
this.displayedName = displayedName;
|
||||
this.baseFactor = baseFactor;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getDisplayedName() {
|
||||
return displayedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value from one dimension unit to this unit.
|
||||
*
|
||||
* @param value the value to convert
|
||||
* @param fromUnit the source unit
|
||||
* @return the converted value
|
||||
* @throws IllegalArgumentException if value or fromUnit is null
|
||||
*/
|
||||
public Double convertFrom(Number value, DimensionUnit fromUnit) {
|
||||
if (value == null || fromUnit == null) {
|
||||
throw new IllegalArgumentException("Value and fromUnit must not be null");
|
||||
}
|
||||
|
||||
// Convert to base unit (millimeters)
|
||||
double valueInBaseUnit = value.doubleValue() * fromUnit.baseFactor;
|
||||
|
||||
// Convert from base unit to target unit
|
||||
return valueInBaseUnit / this.baseFactor;
|
||||
}
|
||||
|
||||
public Double convertFromMM(Number value) {
|
||||
return convertFrom(value, MM);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package de.avatic.lcc.model.packaging;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import de.avatic.lcc.model.materials.Material;
|
||||
import de.avatic.lcc.model.materials.MaterialListEntry;
|
||||
import de.avatic.lcc.model.nodes.Node;
|
||||
import de.avatic.lcc.model.nodes.NodeListEntry;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import jdk.jfr.Unsigned;
|
||||
|
|
@ -13,62 +16,23 @@ import org.springframework.data.relational.core.mapping.Table;
|
|||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a packaging entity in the system. This class defines various
|
||||
* attributes related to a packaging, including its dimensions, weight, type,
|
||||
* and associations with other entities such as material and supplier nodes.
|
||||
* It is used to manage packaging details in the application.
|
||||
*
|
||||
* The packaging entity contains details about its size, weight, and content,
|
||||
* as well as its hierarchical relationship with other packaging or a parent
|
||||
* packaging.
|
||||
*/
|
||||
@Table(name = "packaging")
|
||||
|
||||
public class Packaging {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@NotNull
|
||||
@Size(max = 3)
|
||||
private PackagingType type;
|
||||
|
||||
@Unsigned
|
||||
@NotNull
|
||||
private Integer length;
|
||||
|
||||
@Unsigned
|
||||
@NotNull
|
||||
private Integer width;
|
||||
|
||||
@Unsigned
|
||||
@NotNull
|
||||
private Integer height;
|
||||
|
||||
@NotNull
|
||||
private DimensionUnit displayedDimensionUnit;
|
||||
|
||||
@NotNull
|
||||
private Integer weight;
|
||||
|
||||
@NotNull
|
||||
private WeightUnit displayedWeightUnit;
|
||||
|
||||
@NotNull
|
||||
private Integer contentUnitCount;
|
||||
|
||||
@JsonProperty("is_deprecated")
|
||||
private Boolean isDeprecated;
|
||||
|
||||
@NotNull
|
||||
private AggregateReference<Node,Integer> supplierNode;
|
||||
private NodeListEntry supplier;
|
||||
|
||||
@NotNull
|
||||
private AggregateReference<Material, Integer> material;
|
||||
private MaterialListEntry material;
|
||||
|
||||
private AggregateReference<Packaging, Integer> parent;
|
||||
@JsonProperty("handling_unit")
|
||||
private PackagingDimension hu;
|
||||
|
||||
@MappedCollection(idColumn = "packaging_id")
|
||||
private Set<PackagingProperty> properties;
|
||||
@JsonProperty("small_handling_unit")
|
||||
private PackagingDimension shu;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
|
|
@ -78,70 +42,6 @@ public class Packaging {
|
|||
this.id = id;
|
||||
}
|
||||
|
||||
public PackagingType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(PackagingType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Integer length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Integer getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Integer width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Integer getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Integer height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public DimensionUnit getDisplayedDimensionUnit() {
|
||||
return displayedDimensionUnit;
|
||||
}
|
||||
|
||||
public void setDisplayedDimensionUnit(DimensionUnit displayedDimensionUnit) {
|
||||
this.displayedDimensionUnit = displayedDimensionUnit;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public WeightUnit getDisplayedWeightUnit() {
|
||||
return displayedWeightUnit;
|
||||
}
|
||||
|
||||
public void setDisplayedWeightUnit(WeightUnit displayedWeightUnit) {
|
||||
this.displayedWeightUnit = displayedWeightUnit;
|
||||
}
|
||||
|
||||
public Integer getContentUnitCount() {
|
||||
return contentUnitCount;
|
||||
}
|
||||
|
||||
public void setContentUnitCount(Integer contentUnitCount) {
|
||||
this.contentUnitCount = contentUnitCount;
|
||||
}
|
||||
|
||||
public Boolean getDeprecated() {
|
||||
return isDeprecated;
|
||||
}
|
||||
|
|
@ -150,27 +50,35 @@ public class Packaging {
|
|||
isDeprecated = deprecated;
|
||||
}
|
||||
|
||||
public AggregateReference<Node, Integer> getSupplierNode() {
|
||||
return supplierNode;
|
||||
public NodeListEntry getSupplier() {
|
||||
return supplier;
|
||||
}
|
||||
|
||||
public void setSupplierNode(AggregateReference<Node, Integer> supplierNode) {
|
||||
this.supplierNode = supplierNode;
|
||||
public void setSupplier(NodeListEntry supplier) {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public AggregateReference<Material, Integer> getMaterial() {
|
||||
public MaterialListEntry getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public void setMaterial(AggregateReference<Material, Integer> material) {
|
||||
public void setMaterial(MaterialListEntry material) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public AggregateReference<Packaging, Integer> getParent() {
|
||||
return parent;
|
||||
public PackagingDimension getHu() {
|
||||
return hu;
|
||||
}
|
||||
|
||||
public void setParent(AggregateReference<Packaging, Integer> parent) {
|
||||
this.parent = parent;
|
||||
public void setHu(PackagingDimension hu) {
|
||||
this.hu = hu;
|
||||
}
|
||||
|
||||
public PackagingDimension getShu() {
|
||||
return shu;
|
||||
}
|
||||
|
||||
public void setShu(PackagingDimension shu) {
|
||||
this.shu = shu;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
package de.avatic.lcc.model.packaging;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class PackagingDimension {
|
||||
|
||||
private Integer id;
|
||||
|
||||
private PackagingType type;
|
||||
|
||||
private Double length;
|
||||
|
||||
private Double width;
|
||||
|
||||
private Double height;
|
||||
|
||||
@JsonProperty("dimension_unit")
|
||||
private DimensionUnit dimensionUnit;
|
||||
|
||||
private Double weight;
|
||||
|
||||
@JsonProperty("weight_unit")
|
||||
private WeightUnit weightUnit;
|
||||
|
||||
@JsonProperty("content_unit_count")
|
||||
private Integer contentUnitCount;
|
||||
|
||||
@JsonProperty("is_deprecated")
|
||||
private Boolean isDeprecated;
|
||||
|
||||
public PackagingType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(PackagingType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Double length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public Double getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(Double width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Double getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Double height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public DimensionUnit getDimensionUnit() {
|
||||
return dimensionUnit;
|
||||
}
|
||||
|
||||
public void setDimensionUnit(DimensionUnit dimensionUnit) {
|
||||
this.dimensionUnit = dimensionUnit;
|
||||
}
|
||||
|
||||
public Double getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Double weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public WeightUnit getWeightUnit() {
|
||||
return weightUnit;
|
||||
}
|
||||
|
||||
public void setWeightUnit(WeightUnit weightUnit) {
|
||||
this.weightUnit = weightUnit;
|
||||
}
|
||||
|
||||
public Integer getContentUnitCount() {
|
||||
return contentUnitCount;
|
||||
}
|
||||
|
||||
public void setContentUnitCount(Integer contentUnitCount) {
|
||||
this.contentUnitCount = contentUnitCount;
|
||||
}
|
||||
|
||||
public Boolean getDeprecated() {
|
||||
return isDeprecated;
|
||||
}
|
||||
|
||||
public void setDeprecated(Boolean deprecated) {
|
||||
isDeprecated = deprecated;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package de.avatic.lcc.model.packaging;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import de.avatic.lcc.model.materials.MaterialListEntry;
|
||||
import de.avatic.lcc.model.nodes.NodeListEntry;
|
||||
|
||||
public class PackagingListEntry {
|
||||
|
|
@ -9,33 +10,10 @@ public class PackagingListEntry {
|
|||
|
||||
private NodeListEntry supplier;
|
||||
|
||||
@JsonProperty("parent_id")
|
||||
private Integer parentId;
|
||||
private MaterialListEntry material;
|
||||
|
||||
private Double width;
|
||||
private Double height;
|
||||
private Double length;
|
||||
|
||||
@JsonProperty("dimension_unit")
|
||||
private String dimensionUnit;
|
||||
|
||||
private Double weight;
|
||||
|
||||
@JsonProperty("weight_unit")
|
||||
private String weightUnit;
|
||||
|
||||
@JsonProperty("content_unit_count")
|
||||
private Integer contentUnitCount;
|
||||
|
||||
private String type;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
@JsonProperty("handling_unit")
|
||||
private PackagingDimension hu;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
|
|
@ -53,67 +31,19 @@ public class PackagingListEntry {
|
|||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public Integer getParentId() {
|
||||
return parentId;
|
||||
public MaterialListEntry getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
public void setParentId(Integer parentId) {
|
||||
this.parentId = parentId;
|
||||
public void setMaterial(MaterialListEntry material) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public Double getWidth() {
|
||||
return width;
|
||||
public PackagingDimension getHu() {
|
||||
return hu;
|
||||
}
|
||||
|
||||
public void setWidth(Double width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public Double getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Double height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public Double getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setLength(Double length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public String getDimensionUnit() {
|
||||
return dimensionUnit;
|
||||
}
|
||||
|
||||
public void setDimensionUnit(String dimensionUnit) {
|
||||
this.dimensionUnit = dimensionUnit;
|
||||
}
|
||||
|
||||
public Double getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Double weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public String getWeightUnit() {
|
||||
return weightUnit;
|
||||
}
|
||||
|
||||
public void setWeightUnit(String weightUnit) {
|
||||
this.weightUnit = weightUnit;
|
||||
}
|
||||
|
||||
public Integer getContentUnitCount() {
|
||||
return contentUnitCount;
|
||||
}
|
||||
|
||||
public void setContentUnitCount(Integer contentUnitCount) {
|
||||
this.contentUnitCount = contentUnitCount;
|
||||
public void setHu(PackagingDimension hu) {
|
||||
this.hu = hu;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,16 +7,12 @@ import org.springframework.data.annotation.Id;
|
|||
import org.springframework.data.jdbc.core.mapping.AggregateReference;
|
||||
import org.springframework.data.relational.core.mapping.Table;
|
||||
|
||||
@Table(name = "packaging_property")
|
||||
public class PackagingProperty {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@Size(max = 500)
|
||||
private String propertyValue;
|
||||
|
||||
@NotNull
|
||||
private AggregateReference<PackagingPropertyType,Integer> packagingPropertyType;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package de.avatic.lcc.model.packaging;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* Represents the supported units of weight measurement in the system.
|
||||
|
|
@ -12,8 +13,44 @@ package de.avatic.lcc.model.packaging;
|
|||
* - G: Grams
|
||||
*/
|
||||
public enum WeightUnit {
|
||||
T,
|
||||
KG,
|
||||
G
|
||||
T("t", 1000000.0),
|
||||
KG("kg", 1000.0),
|
||||
G("g", 1.0);
|
||||
|
||||
private final String displayedName;
|
||||
private final double baseFactor;
|
||||
|
||||
WeightUnit(String displayedName, double baseFactor) {
|
||||
this.displayedName = displayedName;
|
||||
this.baseFactor = baseFactor;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getDisplayedName() {
|
||||
return displayedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a value from one weight unit to this unit.
|
||||
*
|
||||
* @param value the value to convert
|
||||
* @param fromUnit the source unit
|
||||
* @return the converted value
|
||||
* @throws IllegalArgumentException if value or fromUnit is null
|
||||
*/
|
||||
public Double convertFrom(Number value, WeightUnit fromUnit) {
|
||||
if (value == null || fromUnit == null) {
|
||||
throw new IllegalArgumentException("Value and fromUnit must not be null");
|
||||
}
|
||||
|
||||
// Convert to base unit (grams)
|
||||
double valueInBaseUnit = value.doubleValue() * fromUnit.baseFactor;
|
||||
|
||||
// Convert from base unit to target unit
|
||||
return valueInBaseUnit / this.baseFactor;
|
||||
}
|
||||
|
||||
public Double convertFromG(Number value) {
|
||||
return convertFrom(value, G);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,10 +4,11 @@ import de.avatic.lcc.model.country.CountryListEntry;
|
|||
import de.avatic.lcc.model.materials.Material;
|
||||
import de.avatic.lcc.model.materials.MaterialListEntry;
|
||||
import de.avatic.lcc.model.nodes.NodeListEntry;
|
||||
import de.avatic.lcc.model.packaging.DimensionUnit;
|
||||
import de.avatic.lcc.model.packaging.PackagingListEntry;
|
||||
import de.avatic.lcc.repositories.utils.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.utils.SearchQueryResult;
|
||||
import de.avatic.lcc.repositories.utils.UnitConverter;
|
||||
import de.avatic.lcc.model.packaging.WeightUnit;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.support.GeneratedKeyHolder;
|
||||
|
|
@ -72,30 +73,33 @@ public class MaterialRepository {
|
|||
|
||||
// Query packaging data for the material
|
||||
String packagingQuery = """
|
||||
SELECT packaging.id, parent_id, width, height, length, packaging.displayed_dimension_unit, weight, displayed_weight_unit,
|
||||
content_unit_count, type,
|
||||
SELECT packaging.id,
|
||||
packaging_dimension.id AS hu_dimension_id, packaging_dimension.displayed_dimension_unit AS displayed_dimension_unit,
|
||||
packaging_dimension.displayed_weight_unit AS displayed_weight_unit, packaging_dimension.width AS width,
|
||||
packaging_dimension.length AS length, packaging_dimension.height AS height,
|
||||
packaging_dimension.content_unit_count AS content_unit_count, packaging_dimension.type AS type,
|
||||
node.id AS supplier_id, node.name AS supplier_name, node.address AS supplier_address,
|
||||
country.id AS country_id, country.name AS country_name, country.iso_code AS country_iso_code, country.region_code AS country_region_code
|
||||
FROM packaging
|
||||
LEFT JOIN packaging_dimension ON packaging.hu_dimension_id = packaging_dimension.id
|
||||
LEFT JOIN node ON packaging.supplier_node_id = node.id
|
||||
LEFT JOIN country ON node.country_id = country.id
|
||||
WHERE material_id = ? AND packaging.is_deprecated = FALSE
|
||||
""";
|
||||
|
||||
if (material != null) {
|
||||
PackagingListEntry packaging = jdbcTemplate.queryForObject(packagingQuery, (packagingRs, packagingRowNum) -> {
|
||||
PackagingListEntry packagingEntry = new PackagingListEntry();
|
||||
|
||||
String dimensionUnit = packagingRs.getString("displayed_dimension_unit");
|
||||
String weightUnit = packagingRs.getString("displayed_weight_unit");
|
||||
DimensionUnit dimensionUnit = DimensionUnit.valueOf(packagingRs.getString("displayed_dimension_unit"));
|
||||
WeightUnit weightUnit = WeightUnit.valueOf(packagingRs.getString("displayed_weight_unit"));
|
||||
|
||||
packagingEntry.setId(packagingRs.getInt("id"));
|
||||
packagingEntry.setParentId(packagingRs.getInt("parent_id"));
|
||||
packagingEntry.setWidth(UnitConverter.convert(packagingRs.getInt("width"), dimensionUnit));
|
||||
packagingEntry.setHeight(UnitConverter.convert(packagingRs.getInt("height"), dimensionUnit));
|
||||
packagingEntry.setLength(UnitConverter.convert(packagingRs.getInt("length"), dimensionUnit));
|
||||
packagingEntry.setWidth(dimensionUnit.convertFromMM(packagingRs.getInt("width")));
|
||||
packagingEntry.setHeight(dimensionUnit.convertFromMM(packagingRs.getInt("height")));
|
||||
packagingEntry.setLength(dimensionUnit.convertFromMM(packagingRs.getInt("length")));
|
||||
packagingEntry.setDimensionUnit(dimensionUnit);
|
||||
packagingEntry.setWeight(UnitConverter.convert(packagingRs.getInt("weight"), weightUnit));
|
||||
packagingEntry.setWeight(weightUnit.convertFromG(packagingRs.getInt("weight")));
|
||||
packagingEntry.setWeightUnit(weightUnit);
|
||||
packagingEntry.setContentUnitCount(packagingRs.getInt("content_unit_count"));
|
||||
packagingEntry.setType(packagingRs.getString("type"));
|
||||
|
|
@ -104,9 +108,9 @@ public class MaterialRepository {
|
|||
NodeListEntry supplier = new NodeListEntry();
|
||||
supplier.setId(packagingRs.getInt("supplier_id"));
|
||||
supplier.setName(packagingRs.getString("supplier_name"));
|
||||
supplier.setAddress(packagingRs.getString("supplier_address"));
|
||||
|
||||
|
||||
if(packagingRs.getObject("country_id") != null) {
|
||||
if (packagingRs.getObject("country_id") != null) {
|
||||
CountryListEntry country = new CountryListEntry();
|
||||
country.setId(packagingRs.getInt("country_id"));
|
||||
country.setName(packagingRs.getString("country_name"));
|
||||
|
|
@ -122,7 +126,6 @@ public class MaterialRepository {
|
|||
}, material.getId());
|
||||
|
||||
material.setPackaging(packaging);
|
||||
}
|
||||
|
||||
return Optional.of(material);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,233 @@
|
|||
package de.avatic.lcc.repositories;
|
||||
|
||||
import de.avatic.lcc.model.country.CountryListEntry;
|
||||
import de.avatic.lcc.model.materials.MaterialListEntry;
|
||||
import de.avatic.lcc.model.nodes.Location;
|
||||
import de.avatic.lcc.model.nodes.NodeListEntry;
|
||||
import de.avatic.lcc.model.nodes.NodeType;
|
||||
import de.avatic.lcc.model.packaging.*;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.PreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public class PackagingRepository {
|
||||
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public PackagingRepository(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public SearchQueryResult<PackagingListEntry> listPackaging(Integer materialId, Integer supplierId, boolean excludeDeprecated, SearchQueryPagination pagination) {
|
||||
|
||||
StringBuilder queryBuilder = new StringBuilder("""
|
||||
SELECT id,
|
||||
FROM packaging
|
||||
WHERE packaging.is_deprecated = ?""");
|
||||
|
||||
if (materialId != null) {
|
||||
queryBuilder.append(" AND material_id = ?");
|
||||
}
|
||||
if (supplierId != null) {
|
||||
queryBuilder.append(" AND supplier_node_id = ?");
|
||||
}
|
||||
queryBuilder.append(" LIMIT ? OFFSET ?");
|
||||
|
||||
var params = new ArrayList<Object>();
|
||||
params.add(excludeDeprecated);
|
||||
if (materialId != null) {
|
||||
params.add(materialId);
|
||||
}
|
||||
if (supplierId != null) {
|
||||
params.add(supplierId);
|
||||
}
|
||||
params.add(pagination.getLimit());
|
||||
params.add(pagination.getOffset());
|
||||
|
||||
var entries = jdbcTemplate.query(queryBuilder.toString(), (rs, rowNum) -> {
|
||||
|
||||
PackagingListEntry data = new PackagingListEntry();
|
||||
|
||||
data.setId(rs.getInt("id"));
|
||||
data.setHu(getPackagingDimensionById(rs.getInt("hu_dimension_id")).orElse(null) );
|
||||
data.setMaterial(getMaterialListEntryById(rs.getInt("material_id")).orElse(null) );
|
||||
data.setSupplier(getNodeListEntryById(rs.getInt("supplier_node_id")).orElse(null) );
|
||||
|
||||
|
||||
return data;
|
||||
}, params.toArray());
|
||||
|
||||
return new SearchQueryResult<>(entries, countPackaging(materialId, supplierId, excludeDeprecated), pagination.getLimit(), pagination.getOffset());
|
||||
}
|
||||
|
||||
private Integer countPackaging(Integer materialId, Integer supplierId, boolean excludeDeprecated) {
|
||||
StringBuilder queryBuilder = new StringBuilder("""
|
||||
SELECT COUNT(*)
|
||||
FROM packaging
|
||||
WHERE packaging.is_deprecated = ?""");
|
||||
|
||||
if (materialId != null) {
|
||||
queryBuilder.append(" AND material_id = ?");
|
||||
}
|
||||
if (supplierId != null) {
|
||||
queryBuilder.append(" AND supplier_node_id = ?");
|
||||
}
|
||||
|
||||
var params = new ArrayList<Object>();
|
||||
params.add(excludeDeprecated);
|
||||
if (materialId != null) {
|
||||
params.add(materialId);
|
||||
}
|
||||
if (supplierId != null) {
|
||||
params.add(supplierId);
|
||||
}
|
||||
|
||||
|
||||
return jdbcTemplate.queryForObject(queryBuilder.toString(), Integer.class, params.toArray());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Transactional
|
||||
public Optional<Packaging> getById(Integer id) {
|
||||
String query = """
|
||||
SELECT id, supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated
|
||||
FROM packaging
|
||||
WHERE packaging.id = ?""";
|
||||
|
||||
var packaging = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
|
||||
var data = new Packaging();
|
||||
|
||||
data.setId(rs.getInt("id"));
|
||||
data.setDeprecated(rs.getBoolean("is_deprecated"));
|
||||
|
||||
data.setHu(getPackagingDimensionById(rs.getInt("hu_dimension_id")).orElse(null) );
|
||||
data.setShu(getPackagingDimensionById(rs.getInt("shu_dimension_id")).orElse(null) );
|
||||
|
||||
data.setMaterial(getMaterialListEntryById(rs.getInt("material_id")).orElse(null) );
|
||||
data.setSupplier(getNodeListEntryById(rs.getInt("supplier_node_id")).orElse(null) );
|
||||
|
||||
return data;
|
||||
}, id);
|
||||
|
||||
return Optional.ofNullable(packaging) ;
|
||||
}
|
||||
|
||||
/* helper to get material preview move to material repo? */
|
||||
private Optional<MaterialListEntry> getMaterialListEntryById(Integer id) {
|
||||
String query = """
|
||||
SELECT material.id AS id, material.name AS name, material.part_number, material.hs_code
|
||||
FROM material
|
||||
WHERE material.id = ?""";
|
||||
|
||||
var material = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
|
||||
var data = new MaterialListEntry();
|
||||
|
||||
data.setId(rs.getInt("id"));
|
||||
data.setName(rs.getString("name"));
|
||||
data.setPartNumber(rs.getString("part_number"));
|
||||
data.setHsCode(rs.getString("hs_code"));
|
||||
|
||||
return data;
|
||||
}, id);
|
||||
|
||||
return Optional.ofNullable(material);
|
||||
}
|
||||
|
||||
private Optional<NodeListEntry> getNodeListEntryById(Integer id) {
|
||||
String query = """
|
||||
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,
|
||||
country.id AS country_id, country.name AS country_name, country.iso_code AS country_iso_code, country.region_code AS country_region_code
|
||||
FROM node
|
||||
LEFT JOIN country ON node.country_id = country.id
|
||||
WHERE node.id = ?""";
|
||||
|
||||
var node = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
|
||||
var data = new NodeListEntry();
|
||||
|
||||
var types = new ArrayList<NodeType>();
|
||||
|
||||
if(rs.getBoolean("is_source")) { types.add(NodeType.SOURCE); };
|
||||
if(rs.getBoolean("is_sink")) { types.add(NodeType.SINK); };
|
||||
if(rs.getBoolean("is_intermediate")) { types.add(NodeType.INTERMEDIATE); };
|
||||
|
||||
var countryData = new CountryListEntry();
|
||||
countryData.setId(rs.getInt("country_id"));
|
||||
countryData.setName(rs.getString("country_name"));
|
||||
countryData.setIsoCode(rs.getString("country_iso_code"));
|
||||
countryData.setRegionCode(rs.getString("country_region_code"));
|
||||
|
||||
data.setId(rs.getInt("id"));
|
||||
data.setName(rs.getString("name"));
|
||||
data.setAddress(rs.getString("address"));
|
||||
data.setCountry(countryData);
|
||||
data.setTypes(types);
|
||||
|
||||
return data;
|
||||
}, id);
|
||||
|
||||
return Optional.ofNullable(node);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<PackagingDimension> getPackagingDimensionById(Integer id) {
|
||||
String query = """
|
||||
SELECT id, displayed_dimension_unit, displayed_weight_unit, width, length, height,
|
||||
content_unit_count, type, is_deprecated
|
||||
FROM packaging_dimension
|
||||
WHERE packaging_dimension.id = ? AND packaging_dimension.is_deprecated = ?""";
|
||||
|
||||
|
||||
var dimension = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
|
||||
var data = new PackagingDimension();
|
||||
|
||||
data.setId(rs.getInt("id"));
|
||||
data.setDimensionUnit(DimensionUnit.valueOf(rs.getString("displayed_dimension_unit")));
|
||||
data.setWeightUnit(WeightUnit.valueOf(rs.getString("displayed_weight_unit")));
|
||||
data.setType(PackagingType.valueOf(rs.getString("type")));
|
||||
data.setDeprecated(rs.getBoolean("is_deprecated"));
|
||||
|
||||
data.setWeight(data.getWeightUnit().convertFromG(rs.getInt("weight")));
|
||||
|
||||
data.setWidth(data.getDimensionUnit().convertFromMM(rs.getInt("width")));
|
||||
data.setHeight(data.getDimensionUnit().convertFromMM(rs.getInt("height")));
|
||||
data.setLength(data.getDimensionUnit().convertFromMM(rs.getInt("length")));
|
||||
|
||||
return data;
|
||||
}, id);
|
||||
|
||||
return Optional.ofNullable(dimension);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void update(Packaging packaging) {
|
||||
//
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<Integer> deleteById(Integer id) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Optional<Integer> create(Packaging packaging) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package de.avatic.lcc.repositories.utils;
|
||||
package de.avatic.lcc.repositories.pagination;
|
||||
|
||||
public class SearchQueryPagination {
|
||||
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package de.avatic.lcc.repositories.pagination;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Represents the result of a search query with pagination, holding the list of results
|
||||
* and metadata related to the pagination (such as current page, total pages, and total elements).
|
||||
* <p>
|
||||
* A replacement for org.springframework.data.domain.Page, since this project uses spring jdbc
|
||||
*
|
||||
* @param <T> The type of the elements contained in the result.
|
||||
*/
|
||||
public class SearchQueryResult<T> {
|
||||
|
||||
private List<T> result;
|
||||
|
||||
private Integer page, totalPages, totalElements;
|
||||
|
||||
/**
|
||||
* Constructs a new SearchQueryResult with the given result list and pagination metadata.
|
||||
*
|
||||
* @param result The list of results for the query.
|
||||
* @param page The current page number (0-indexed).
|
||||
* @param totalPages The total number of pages.
|
||||
* @param totalElements The total number of elements across all pages.
|
||||
*/
|
||||
public SearchQueryResult(List<T> result, Integer page, Integer totalPages, Integer totalElements) {
|
||||
this.result = result;
|
||||
this.page = page;
|
||||
this.totalPages = totalPages;
|
||||
this.totalElements = totalElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of results in this SearchQueryResult.
|
||||
*
|
||||
* @return The list of query results.
|
||||
*/
|
||||
public List<T> toList() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of results for this SearchQueryResult.
|
||||
*
|
||||
* @param result The list of query results to set.
|
||||
*/
|
||||
public void setResult(List<T> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current page number of this SearchQueryResult (0-indexed).
|
||||
*
|
||||
* @return The current page number.
|
||||
*/
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current page number of this SearchQueryResult (0-indexed).
|
||||
*
|
||||
* @param page The page number to set.
|
||||
*/
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of pages in this SearchQueryResult.
|
||||
*
|
||||
* @return The total number of pages.
|
||||
*/
|
||||
public int getTotalPages() {
|
||||
return totalPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total number of pages for this SearchQueryResult.
|
||||
*
|
||||
* @param totalPages The total number of pages to set.
|
||||
*/
|
||||
public void setTotalPages(int totalPages) {
|
||||
this.totalPages = totalPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of elements in the search results.
|
||||
*
|
||||
* @return The total number of elements.
|
||||
*/
|
||||
public int getTotalElements() {
|
||||
return totalElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the total number of elements in the search results.
|
||||
*
|
||||
* @param totalElements The total number of elements to set.
|
||||
*/
|
||||
public void setTotalElements(int totalElements) {
|
||||
this.totalElements = totalElements;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package de.avatic.lcc.repositories.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SearchQueryResult<T> {
|
||||
|
||||
private List<T> result;
|
||||
|
||||
private Integer page, totalPages, totalElements;
|
||||
|
||||
public SearchQueryResult(List<T> result, Integer page, Integer totalPages, Integer totalElements) {
|
||||
this.result = result;
|
||||
this.page = page;
|
||||
this.totalPages = totalPages;
|
||||
this.totalElements = totalElements;
|
||||
}
|
||||
|
||||
public List<T> toList() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(List<T> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
}
|
||||
|
||||
public void setPage(int page) {
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public int getTotalPages() {
|
||||
return totalPages;
|
||||
}
|
||||
|
||||
public void setTotalPages(int totalPages) {
|
||||
this.totalPages = totalPages;
|
||||
}
|
||||
|
||||
public int getTotalElements() {
|
||||
return totalElements;
|
||||
}
|
||||
|
||||
public void setTotalElements(int totalElements) {
|
||||
this.totalElements = totalElements;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,8 @@ package de.avatic.lcc.service;
|
|||
import de.avatic.lcc.model.materials.Material;
|
||||
import de.avatic.lcc.model.materials.MaterialListEntry;
|
||||
import de.avatic.lcc.repositories.MaterialRepository;
|
||||
import de.avatic.lcc.repositories.utils.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.utils.SearchQueryResult;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
|
|
|
|||
39
src/main/java/de/avatic/lcc/service/PackagingService.java
Normal file
39
src/main/java/de/avatic/lcc/service/PackagingService.java
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package de.avatic.lcc.service;
|
||||
|
||||
import de.avatic.lcc.model.packaging.Packaging;
|
||||
import de.avatic.lcc.model.packaging.PackagingListEntry;
|
||||
import de.avatic.lcc.repositories.PackagingRepository;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
|
||||
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PackagingService {
|
||||
private final PackagingRepository packagingRepository;
|
||||
|
||||
public PackagingService(PackagingRepository packagingRepository) {
|
||||
this.packagingRepository = packagingRepository;
|
||||
}
|
||||
|
||||
public SearchQueryResult<PackagingListEntry> listPackaging(Integer materialId, Integer supplierId, int page, int limit) {
|
||||
return packagingRepository.listPackaging(materialId, supplierId, true, new SearchQueryPagination(page, limit));
|
||||
}
|
||||
|
||||
|
||||
public void updatePackaging(Integer id, Packaging packaging) {
|
||||
packaging.setId(id);
|
||||
packagingRepository.update(packaging);
|
||||
}
|
||||
|
||||
public Integer deletePackaging(Integer id) {
|
||||
return packagingRepository.deleteById(id).orElseThrow(() -> new RuntimeException("Packaging does not exists " + id));
|
||||
}
|
||||
|
||||
public Integer addPackaging(Packaging packaging) {
|
||||
return packagingRepository.create(packaging).orElseThrow(() -> new RuntimeException("Unable to create Packaging " + packaging));
|
||||
}
|
||||
|
||||
public Packaging getPackaging(Integer id) {
|
||||
return packagingRepository.getById(id).orElseThrow(() -> new RuntimeException("Packaging does not exists " + id));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue