Remove outdated DTOs and refactor material-related services

Removed legacy DTOs (`PackagingDTO`, `PackagingListEntry`, etc.) that were no longer in use. Introduced modular, type-specific DTOs (`MaterialGetDTO`, `MaterialPostDTO`, etc.) and improved service layer responsibilities with a new `MaterialTransformerService`. This enhances maintainability and prepares for future feature extensions.
This commit is contained in:
Jan 2025-03-28 21:35:55 +01:00
parent 631a5c2f53
commit c5096b129b
58 changed files with 2286 additions and 897 deletions

View file

@ -0,0 +1,41 @@
package de.avatic.lcc.controller;
import de.avatic.lcc.dto.countries.get.CountryGetDTO;
import de.avatic.lcc.dto.countries.get.CountryListGetDTO;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.CountryService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/countries")
public class CountryController {
private final CountryService countryService;
public CountryController(CountryService countryService) {
this.countryService = countryService;
}
@GetMapping("/")
public ResponseEntity<List<CountryListGetDTO>> listCountries(@RequestParam(defaultValue = "20") int limit,
@RequestParam(defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "") String filter) {
SearchQueryResult<CountryListGetDTO> countries = countryService.listMaterial(filter, page, limit);
return ResponseEntity.ok()
.header("X-Total-Count", String.valueOf(countries.getTotalElements()))
.header("X-Page-Count", String.valueOf(countries.getTotalPages()))
.header("X-Current-Page", String.valueOf(page))
.body(countries.toList());
}
@GetMapping("/{id}")
public ResponseEntity<CountryGetDTO> getCountryDetails(@PathVariable Integer id) {
return ResponseEntity.ok(countryService.getCountry(id));
}
}

View file

@ -1,7 +1,9 @@
package de.avatic.lcc.controller;
import de.avatic.lcc.dto.material.get.MaterialGetDTO;
import de.avatic.lcc.dto.material.post.MaterialPostDTO;
import de.avatic.lcc.model.materials.Material;
import de.avatic.lcc.model.materials.MaterialListEntry;
import de.avatic.lcc.dto.material.get.MaterialListGetDTO;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.MaterialService;
import org.springframework.beans.factory.annotation.Autowired;
@ -32,12 +34,12 @@ public class MaterialController {
* X-Total-Count (total elements), X-Page-Count (total pages), and X-Current-Page (current page).
*/
@GetMapping("/")
public ResponseEntity<List<MaterialListEntry>> listMaterials(
public ResponseEntity<List<MaterialListGetDTO>> listMaterials(
@RequestParam(defaultValue = "20") int limit,
@RequestParam(defaultValue = "0") int page,
@RequestParam(required = false, defaultValue = "") String filter) {
SearchQueryResult<MaterialListEntry> materials = materialService.listMaterials(filter, page, limit);
SearchQueryResult<MaterialListGetDTO> materials = materialService.listMaterial(filter, page, limit);
return ResponseEntity.ok()
.header("X-Total-Count", String.valueOf(materials.getTotalElements()))
@ -54,7 +56,7 @@ public class MaterialController {
* @throws RuntimeException if the material with the given ID is not found.
*/
@GetMapping("/{id}")
public ResponseEntity<Material> getMaterialDetails(@PathVariable Integer id) {
public ResponseEntity<MaterialGetDTO> getMaterialDetails(@PathVariable Integer id) {
return ResponseEntity.ok(materialService.getMaterial(id));
}
@ -68,8 +70,9 @@ public class MaterialController {
@PutMapping("/{id}")
public ResponseEntity<Material> updateMaterial(
@PathVariable Integer id,
@RequestBody Material material) {
return ResponseEntity.ok(materialService.updateMaterial(id, material));
@RequestBody MaterialPostDTO material) {
materialService.updateMaterial(id, material);
return ResponseEntity.noContent().build();
}
/**
@ -81,12 +84,11 @@ public class MaterialController {
*/
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteMaterial(@PathVariable Integer id) {
materialService.deleteMaterial(id);
return ResponseEntity.noContent().build();
ResponseEntity.ok(materialService.deleteMaterial(id));
}
@PostMapping("/")
public ResponseEntity<Integer> createMaterial(@RequestBody Material material) {
public ResponseEntity<Integer> createMaterial(@RequestBody MaterialPostDTO material) {
return ResponseEntity.ok(materialService.createMaterial(material));
}
}

View file

@ -1,8 +1,8 @@
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.dto.packaging.get.PackagingGetDTO;
import de.avatic.lcc.dto.packaging.post.PackagingPostDTO;
import de.avatic.lcc.repositories.packaging.PackagingRepository;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.PackagingService;
import org.springframework.beans.factory.annotation.Autowired;
@ -25,13 +25,13 @@ public class PackagingController {
}
@GetMapping("/")
public ResponseEntity<List<PackagingListEntry>> listPackaging(
public ResponseEntity<List<PackagingGetDTO>> 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);
SearchQueryResult<PackagingGetDTO> listEntries = packagingService.listPackaging(materialId, supplierId, page, limit);
return ResponseEntity.ok()
.header("X-Total-Count", String.valueOf(listEntries.getTotalElements()))
@ -43,13 +43,13 @@ public class PackagingController {
}
@GetMapping("/{id}")
public ResponseEntity<Packaging> getPackagingDetails(@PathVariable Integer id) {
public ResponseEntity<PackagingGetDTO> getPackagingDetails(@PathVariable Integer id) {
return ResponseEntity.ok(packagingService.getPackaging(id));
}
@PutMapping("/{id}")
public ResponseEntity<Void> updatePackaging(@PathVariable Integer id, @RequestBody Packaging packaging) {
public ResponseEntity<Void> updatePackaging(@PathVariable Integer id, @RequestBody PackagingPostDTO packaging) {
packagingService.updatePackaging(id, packaging);
return ResponseEntity.noContent().build();
}
@ -61,8 +61,8 @@ public class PackagingController {
}
@PostMapping("/")
public ResponseEntity<Integer> addPackaging(@RequestBody Packaging packaging) {
return ResponseEntity.ok(packagingService.addPackaging(packaging));
public ResponseEntity<Integer> addPackaging(@RequestBody PackagingPostDTO packaging) {
return ResponseEntity.ok(packagingService.createPackaging(packaging));
}

View file

@ -0,0 +1,60 @@
package de.avatic.lcc.dto.countries.get;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collection;
public class CountryGetDTO {
private Integer id;
private String name;
@JsonProperty("iso_code")
private String isoCode;
@JsonProperty("region_code")
private String regionCode;
private Collection<CountryPropertyGetDTO> properties;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIsoCode() {
return isoCode;
}
public void setIsoCode(String isoCode) {
this.isoCode = isoCode;
}
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
public Collection<CountryPropertyGetDTO> getProperties() {
return properties;
}
public void setProperties(Collection<CountryPropertyGetDTO> properties) {
this.properties = properties;
}
}

View file

@ -1,13 +1,12 @@
package de.avatic.lcc.dto.countries;
package de.avatic.lcc.dto.countries.get;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CountryDTO {
public class CountryListGetDTO {
//TODO add country properties
private Integer id;
@JsonProperty("id")
private String id;
private String name;
@JsonProperty("iso_code")
private String isoCode;
@ -15,17 +14,22 @@ public class CountryDTO {
@JsonProperty("region_code")
private String regionCode;
@JsonProperty("name")
private String name;
public String getId() {
public Integer getId() {
return id;
}
public void setId(String id) {
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIsoCode() {
return isoCode;
}
@ -42,12 +46,11 @@ public class CountryDTO {
this.regionCode = regionCode;
}
public String getName() {
return name;
@Override
public String toString() {
return "CountryListGetDTO{" +
"id=" + id +
", isoCode='" + isoCode + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
}

View file

@ -0,0 +1,81 @@
package de.avatic.lcc.dto.countries.get;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CountryPropertyGetDTO {
private Integer id;
private String name;
@JsonProperty("external_mapping_id")
private String externalMappingId;
@JsonProperty("is_required")
private Boolean isRequired;
@JsonProperty("data_type")
private String dataType;
@JsonProperty("current_value")
private String currentValue;
@JsonProperty("draft_value")
private String draftValue;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getExternalMappingId() {
return externalMappingId;
}
public void setExternalMappingId(String externalMappingId) {
this.externalMappingId = externalMappingId;
}
public Boolean getRequired() {
return isRequired;
}
public void setRequired(Boolean required) {
isRequired = required;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getCurrentValue() {
return currentValue;
}
public void setCurrentValue(String currentValue) {
this.currentValue = currentValue;
}
public String getDraftValue() {
return draftValue;
}
public void setDraftValue(String draftValue) {
this.draftValue = draftValue;
}
}

View file

@ -1,13 +1,15 @@
package de.avatic.lcc.model.nodes;
package de.avatic.lcc.dto.generic;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.ArrayList;
/**
* Represents the various types of nodes that can exist in the system.
* A node can be categorized as SINK, SOURCE, or INTERMEDIATE, depending
* on its role within a network or process.
*/
public enum NodeType {
public enum NodeTypeDTO {
/**
* Represents a node that consumes resources or products (end-point of flow).
*/
@ -30,7 +32,7 @@ public enum NodeType {
*
* @param displayedType The string representation of the node type.
*/
NodeType(String displayedType) {
NodeTypeDTO(String displayedType) {
this.displayedType = displayedType;
}
@ -43,4 +45,6 @@ public enum NodeType {
public String getDisplayedType() {
return displayedType;
}
}

View file

@ -1,148 +0,0 @@
package de.avatic.lcc.dto.material;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
public class PackagingDTO {
private String id;
@JsonProperty("supplier_name")
private SupplierDTO supplierName;
@JsonProperty("parent_id")
private String parentId;
private double length;
private double width;
private double height;
@JsonProperty("dimension_unit")
private String dimensionUnit;
private double weight;
@JsonProperty("weight_unit")
private String weightUnit;
@JsonProperty("content_unit_count")
private int contentUnitCount;
public PackagingDTO() {
}
public PackagingDTO(String id, String supplierName, String parentId, double length, double width, double height,
String dimensionUnit, double weight, String weightUnit, int contentUnitCount) {
this.id = id;
this.supplierName = supplierName;
this.parentId = parentId;
this.length = length;
this.width = width;
this.height = height;
this.dimensionUnit = dimensionUnit;
this.weight = weight;
this.weightUnit = weightUnit;
this.contentUnitCount = contentUnitCount;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@JsonProperty("supplier_name")
public String getSupplierName() {
return supplierName;
}
@JsonProperty("supplier_name")
public void setSupplierName(String supplierName) {
this.supplierName = supplierName;
}
@JsonProperty("parent_id")
public String getParentId() {
return parentId;
}
@JsonProperty("parent_id")
public void setParentId(String parentId) {
this.parentId = parentId;
}
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;
}
@JsonProperty("dimension_unit")
public String getDimensionUnit() {
return dimensionUnit;
}
@JsonProperty("dimension_unit")
public void setDimensionUnit(String dimensionUnit) {
this.dimensionUnit = dimensionUnit;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
@JsonProperty("weight_unit")
public String getWeightUnit() {
return weightUnit;
}
@JsonProperty("weight_unit")
public void setWeightUnit(String weightUnit) {
this.weightUnit = weightUnit;
}
@JsonProperty("content_unit_count")
public int getContentUnitCount() {
return contentUnitCount;
}
@JsonProperty("content_unit_count")
public void setContentUnitCount(int contentUnitCount) {
this.contentUnitCount = contentUnitCount;
}
@Override
public String toString() {
// Implementation omitted for shortness
return "HandlingUnitDTO{" + /* fields */ "}";
}
@Override
public boolean equals(Object o) {
// Implementation omitted for shortness
return true;
}
@Override
public int hashCode() {
// Implementation omitted for shortness
return Objects.hash(id, supplierName, parentId, length, width, height, dimensionUnit,
weight, weightUnit, contentUnitCount);
}
}

View file

@ -0,0 +1,40 @@
package de.avatic.lcc.dto.material.get;
import com.fasterxml.jackson.annotation.JsonProperty;
public class MaterialCountryGetDTO {
@JsonProperty("id")
private Integer id;
@JsonProperty("iso_code")
private String isoCode;
@JsonProperty("region_code")
private String regionCode;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getIsoCode() {
return isoCode;
}
public void setIsoCode(String isoCode) {
this.isoCode = isoCode;
}
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
}

View file

@ -0,0 +1,113 @@
package de.avatic.lcc.dto.material.get;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.model.packaging.PackagingType;
import de.avatic.lcc.model.utils.DimensionUnit;
import de.avatic.lcc.model.utils.WeightUnit;
public class MaterialDimensionGetDTO {
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;
}
}

View file

@ -1,12 +1,12 @@
package de.avatic.lcc.dto.material;
package de.avatic.lcc.dto.material.get;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import java.util.Objects;
public class MaterialDTO {
private String id;
public class MaterialGetDTO {
private Integer id;
@JsonProperty("part_number")
private String partNumber;
@ -16,13 +16,14 @@ public class MaterialDTO {
@JsonProperty("hs_code")
private String hsCode;
@JsonProperty("handling_units")
private List<PackagingDTO> handlingUnits;
public MaterialDTO() {
@JsonProperty("packaging")
private List<MaterialPackagingGetDTO> handlingUnits;
public MaterialGetDTO() {
}
public MaterialDTO(String id, String partNumber, String name, String hs_code, List<PackagingDTO> handling_units) {
public MaterialGetDTO(Integer id, String partNumber, String name, String hs_code, List<MaterialPackagingGetDTO> handling_units) {
this.id = id;
this.partNumber = partNumber;
this.name = name;
@ -30,11 +31,11 @@ public class MaterialDTO {
this.handlingUnits = handling_units;
}
public String getId() {
public Integer getId() {
return id;
}
public void setId(String id) {
public void setId(Integer id) {
this.id = id;
}
@ -67,11 +68,11 @@ public class MaterialDTO {
}
@JsonProperty("handling_units")
public List<PackagingDTO> getHandlingUnits() {
public List<MaterialPackagingGetDTO> getHandlingUnits() {
return handlingUnits;
}
public void setHandlingUnits(List<PackagingDTO> handlingUnits) {
public void setHandlingUnits(List<MaterialPackagingGetDTO> handlingUnits) {
this.handlingUnits = handlingUnits;
}
@ -90,7 +91,7 @@ public class MaterialDTO {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MaterialDTO that = (MaterialDTO) o;
MaterialGetDTO that = (MaterialGetDTO) o;
return Objects.equals(id, that.id) &&
Objects.equals(partNumber, that.partNumber) &&
Objects.equals(name, that.name) &&

View file

@ -0,0 +1,82 @@
package de.avatic.lcc.dto.material.get;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
public class MaterialListGetDTO {
private Integer id;
@JsonProperty("part_number")
private String partNumber;
private String name;
private String hsCode;
public MaterialListGetDTO() {
}
public MaterialListGetDTO(Integer id, String partNumber, String name, String hsCode) {
this.id = id;
this.partNumber = partNumber;
this.name = name;
this.hsCode = hsCode;
}
public String getHsCode() {
return hsCode;
}
public void setHsCode(String hsCode) {
this.hsCode = hsCode;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPartNumber() {
return partNumber;
}
public void setPartNumber(String partNumber) {
this.partNumber = partNumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MaterialSummaryDTO{" +
"id='" + id + '\'' +
", partNumber='" + partNumber + '\'' +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MaterialListGetDTO that = (MaterialListGetDTO) o;
return Objects.equals(id, that.id) &&
Objects.equals(partNumber, that.partNumber) &&
Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(id, partNumber, name);
}
}

View file

@ -0,0 +1,59 @@
package de.avatic.lcc.dto.material.get;
import com.fasterxml.jackson.annotation.JsonProperty;
public class MaterialPackagingGetDTO {
private Integer id;
@JsonProperty("is_deprecated")
private Boolean isDeprecated;
private MaterialSupplierGetDTO supplier;
@JsonProperty("handling_unit")
private MaterialDimensionGetDTO hu;
@JsonProperty("small_handling_unit")
private MaterialDimensionGetDTO shu;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Boolean getDeprecated() {
return isDeprecated;
}
public void setDeprecated(Boolean deprecated) {
isDeprecated = deprecated;
}
public MaterialSupplierGetDTO getSupplier() {
return supplier;
}
public void setSupplier(MaterialSupplierGetDTO supplier) {
this.supplier = supplier;
}
public MaterialDimensionGetDTO getHu() {
return hu;
}
public void setHu(MaterialDimensionGetDTO hu) {
this.hu = hu;
}
public MaterialDimensionGetDTO getShu() {
return shu;
}
public void setShu(MaterialDimensionGetDTO shu) {
this.shu = shu;
}
}

View file

@ -0,0 +1,67 @@
package de.avatic.lcc.dto.material.get;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.dto.generic.NodeTypeDTO;
import de.avatic.lcc.dto.packaging.get.PackagingCountryGetDTO;
import java.util.List;
public class MaterialSupplierGetDTO {
private Integer id;
private String name;
private MaterialCountryGetDTO country;
private String address;
private List<NodeTypeDTO> types;
@JsonProperty("is_deprecated")
private Boolean isDeprecated;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MaterialCountryGetDTO getCountry() {
return country;
}
public void setCountry(MaterialCountryGetDTO country) {
this.country = country;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<NodeTypeDTO> getTypes() {
return types;
}
public void setTypes(List<NodeTypeDTO> types) {
this.types = types;
}
public Boolean getDeprecated() {
return isDeprecated;
}
public void setDeprecated(Boolean deprecated) {
isDeprecated = deprecated;
}
}

View file

@ -1,22 +1,20 @@
package de.avatic.lcc.model.materials;
package de.avatic.lcc.dto.material.post;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
public class MaterialListEntry {
public class MaterialPostDTO {
private Integer id;
@JsonProperty("part_number")
private String partNumber;
private String name;
private String hsCode;
public MaterialListEntry() {
public MaterialPostDTO() {
}
public MaterialListEntry(Integer id, String partNumber, String name, String hsCode) {
public MaterialPostDTO(Integer id, String partNumber, String name, String hsCode) {
this.id = id;
this.partNumber = partNumber;
this.name = name;
@ -68,7 +66,7 @@ public class MaterialListEntry {
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MaterialListEntry that = (MaterialListEntry) o;
MaterialPostDTO that = (MaterialPostDTO) o;
return Objects.equals(id, that.id) &&
Objects.equals(partNumber, that.partNumber) &&
Objects.equals(name, that.name);

View file

@ -1,11 +1,11 @@
package de.avatic.lcc.dto.countries;
package de.avatic.lcc.dto.packaging.get;
import com.fasterxml.jackson.annotation.JsonProperty;
public class CountryOverviewDTO {
public class PackagingCountryGetDTO {
@JsonProperty("id")
private String id;
private Integer id;
@JsonProperty("iso_code")
private String isoCode;
@ -13,14 +13,12 @@ public class CountryOverviewDTO {
@JsonProperty("region_code")
private String regionCode;
@JsonProperty("name")
private String name;
public String getId() {
public Integer getId() {
return id;
}
public void setId(String id) {
public void setId(Integer id) {
this.id = id;
}
@ -40,11 +38,4 @@ public class CountryOverviewDTO {
this.regionCode = regionCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View file

@ -0,0 +1,113 @@
package de.avatic.lcc.dto.packaging.get;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.model.packaging.PackagingType;
import de.avatic.lcc.model.utils.DimensionUnit;
import de.avatic.lcc.model.utils.WeightUnit;
public class PackagingDimensionGetDTO {
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;
}
}

View file

@ -0,0 +1,70 @@
package de.avatic.lcc.dto.packaging.get;
import com.fasterxml.jackson.annotation.JsonProperty;
public class PackagingGetDTO {
private Integer id;
@JsonProperty("is_deprecated")
private Boolean isDeprecated;
private PackagingSupplierGetDTO supplier;
private PackagingMaterialGetDTO material;
@JsonProperty("handling_unit")
private PackagingDimensionGetDTO hu;
@JsonProperty("small_handling_unit")
private PackagingDimensionGetDTO shu;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Boolean getDeprecated() {
return isDeprecated;
}
public void setDeprecated(Boolean deprecated) {
isDeprecated = deprecated;
}
public PackagingSupplierGetDTO getSupplier() {
return supplier;
}
public void setSupplier(PackagingSupplierGetDTO supplier) {
this.supplier = supplier;
}
public PackagingMaterialGetDTO getMaterial() {
return material;
}
public void setMaterial(PackagingMaterialGetDTO material) {
this.material = material;
}
public PackagingDimensionGetDTO getHu() {
return hu;
}
public void setHu(PackagingDimensionGetDTO hu) {
this.hu = hu;
}
public PackagingDimensionGetDTO getShu() {
return shu;
}
public void setShu(PackagingDimensionGetDTO shu) {
this.shu = shu;
}
}

View file

@ -1,8 +1,8 @@
package de.avatic.lcc.model.packaging;
package de.avatic.lcc.dto.packaging.get;
import com.fasterxml.jackson.annotation.JsonProperty;
public class PackagingMaterial {
public class PackagingMaterialGetDTO {
private Integer id;
@JsonProperty("part_number")

View file

@ -1,26 +1,20 @@
package de.avatic.lcc.model.packaging;
package de.avatic.lcc.dto.packaging.get;
import de.avatic.lcc.model.country.CountryListEntry;
import de.avatic.lcc.model.nodes.NodeType;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.dto.generic.NodeTypeDTO;
import java.util.List;
public class PackagingSupplier {
public class PackagingSupplierGetDTO {
private Integer id;
private String name;
private CountryListEntry country;
private PackagingCountryGetDTO country;
private String address;
private List<NodeType> types;
private List<NodeTypeDTO> types;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonProperty("is_deprecated")
private Boolean isDeprecated;
public Integer getId() {
return id;
@ -30,11 +24,19 @@ public class PackagingSupplier {
this.id = id;
}
public CountryListEntry getCountry() {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public PackagingCountryGetDTO getCountry() {
return country;
}
public void setCountry(CountryListEntry country) {
public void setCountry(PackagingCountryGetDTO country) {
this.country = country;
}
@ -46,11 +48,15 @@ public class PackagingSupplier {
this.address = address;
}
public List<NodeType> getTypes() {
public List<NodeTypeDTO> getTypes() {
return types;
}
public void setTypes(List<NodeType> types) {
public void setTypes(List<NodeTypeDTO> types) {
this.types = types;
}
public void setDeprecated(Boolean isDeprecated) {
this.isDeprecated = isDeprecated;
}
}

View file

@ -0,0 +1,73 @@
package de.avatic.lcc.dto.packaging.post;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.dto.packaging.get.PackagingDimensionGetDTO;
import de.avatic.lcc.dto.packaging.get.PackagingMaterialGetDTO;
import de.avatic.lcc.dto.packaging.get.PackagingSupplierGetDTO;
public class PackagingPostDTO {
private Integer id;
@JsonProperty("is_deprecated")
private Boolean isDeprecated;
private Integer supplierId;
private Integer materialId;
@JsonProperty("handling_unit")
private PackagingDimensionGetDTO hu;
@JsonProperty("small_handling_unit")
private PackagingDimensionGetDTO shu;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Boolean getDeprecated() {
return isDeprecated;
}
public void setDeprecated(Boolean deprecated) {
isDeprecated = deprecated;
}
public Integer getSupplierId() {
return supplierId;
}
public void setSupplierId(Integer supplierId) {
this.supplierId = supplierId;
}
public Integer getMaterialId() {
return materialId;
}
public void setMaterialId(Integer materialId) {
this.materialId = materialId;
}
public PackagingDimensionGetDTO getHu() {
return hu;
}
public void setHu(PackagingDimensionGetDTO hu) {
this.hu = hu;
}
public PackagingDimensionGetDTO getShu() {
return shu;
}
public void setShu(PackagingDimensionGetDTO shu) {
this.shu = shu;
}
}

View file

@ -21,9 +21,6 @@ public class Country {
@Size(max=5)
private RegionCode regionCode;
@NotNull
@Size(max=128)
private String name;
@NotNull
private Boolean isDeprecated;
@ -52,14 +49,6 @@ public class Country {
this.regionCode = regionCode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boolean getDeprecated() {
return isDeprecated;
}

View file

@ -6,19 +6,65 @@ package de.avatic.lcc.model.country;
*/
public enum IsoCode {
AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ,
BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BR, BS, BT, BV, BW, BY, BZ,
CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ,
DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR,
GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY,
HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP,
KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY,
MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ,
NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY,
QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ,
TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ,
VA, VC, VE, VG, VI, VN, VU, WF, WS, YE, YT, ZA, ZM, ZW;
AD("Andorra"), AE("United Arab Emirates"), AF("Afghanistan"), AG("Antigua and Barbuda"), AI("Anguilla"),
AL("Albania"), AM("Armenia"), AO("Angola"), AQ("Antarctica"), AR("Argentina"),
AS("American Samoa"), AT("Austria"), AU("Australia"), AW("Aruba"), AX("Åland Islands"),
AZ("Azerbaijan"), BA("Bosnia and Herzegovina"), BB("Barbados"), BD("Bangladesh"),
BE("Belgium"), BF("Burkina Faso"), BG("Bulgaria"), BH("Bahrain"), BI("Burundi"),
BJ("Benin"), BL("Saint Barthélemy"), BM("Bermuda"), BN("Brunei"), BO("Bolivia"),
BR("Brazil"), BS("Bahamas"), BT("Bhutan"), BV("Bouvet Island"), BW("Botswana"),
BY("Belarus"), BZ("Belize"), CA("Canada"), CC("Cocos Islands"), CD("Democratic Republic of the Congo"),
CF("Central African Republic"), CG("Republic of the Congo"), CH("Switzerland"), CI("Ivory Coast"),
CK("Cook Islands"), CL("Chile"), CM("Cameroon"), CN("China"), CO("Colombia"),
CR("Costa Rica"), CU("Cuba"), CV("Cape Verde"), CW("Curaçao"), CX("Christmas Island"),
CY("Cyprus"), CZ("Czech Republic"), DE("Germany"), DJ("Djibouti"), DK("Denmark"),
DM("Dominica"), DO("Dominican Republic"), DZ("Algeria"), EC("Ecuador"), EE("Estonia"),
EG("Egypt"), EH("Western Sahara"), ER("Eritrea"), ES("Spain"), ET("Ethiopia"),
FI("Finland"), FJ("Fiji"), FK("Falkland Islands"), FM("Micronesia"), FO("Faroe Islands"),
FR("France"), GA("Gabon"), GB("United Kingdom"), GD("Grenada"), GE("Georgia"),
GF("French Guiana"), GG("Guernsey"), GH("Ghana"), GI("Gibraltar"), GL("Greenland"),
GM("Gambia"), GN("Guinea"), GP("Guadeloupe"), GQ("Equatorial Guinea"), GR("Greece"),
GS("South Georgia and the South Sandwich Islands"), GT("Guatemala"), GU("Guam"),
GW("Guinea-Bissau"), GY("Guyana"), HK("Hong Kong"), HM("Heard Island and McDonald Islands"),
HN("Honduras"), HR("Croatia"), HT("Haiti"), HU("Hungary"), ID("Indonesia"),
IE("Ireland"), IL("Israel"), IM("Isle of Man"), IN("India"), IO("British Indian Ocean Territory"),
IQ("Iraq"), IR("Iran"), IS("Iceland"), IT("Italy"), JE("Jersey"), JM("Jamaica"),
JO("Jordan"), JP("Japan"), KE("Kenya"), KG("Kyrgyzstan"), KH("Cambodia"),
KI("Kiribati"), KM("Comoros"), KN("Saint Kitts and Nevis"), KP("North Korea"),
KR("South Korea"), KW("Kuwait"), KY("Cayman Islands"), KZ("Kazakhstan"), LA("Laos"),
LB("Lebanon"), LC("Saint Lucia"), LI("Liechtenstein"), LK("Sri Lanka"), LR("Liberia"),
LS("Lesotho"), LT("Lithuania"), LU("Luxembourg"), LV("Latvia"), LY("Libya"),
MA("Morocco"), MC("Monaco"), MD("Moldova"), ME("Montenegro"), MF("Saint Martin"),
MG("Madagascar"), MH("Marshall Islands"), MK("North Macedonia"), ML("Mali"),
MM("Myanmar"), MN("Mongolia"), MO("Macao"), MP("Northern Mariana Islands"),
MQ("Martinique"), MR("Mauritania"), MS("Montserrat"), MT("Malta"), MU("Mauritius"),
MV("Maldives"), MW("Malawi"), MX("Mexico"), MY("Malaysia"), MZ("Mozambique"),
NA("Namibia"), NC("New Caledonia"), NE("Niger"), NF("Norfolk Island"), NG("Nigeria"),
NI("Nicaragua"), NL("Netherlands"), NO("Norway"), NP("Nepal"), NR("Nauru"),
NU("Niue"), NZ("New Zealand"), OM("Oman"), PA("Panama"), PE("Peru"),
PF("French Polynesia"), PG("Papua New Guinea"), PH("Philippines"), PK("Pakistan"),
PL("Poland"), PM("Saint Pierre and Miquelon"), PN("Pitcairn"), PR("Puerto Rico"),
PS("Palestine"), PT("Portugal"), PW("Palau"), PY("Paraguay"), QA("Qatar"),
RE("Réunion"), RO("Romania"), RS("Serbia"), RU("Russia"), RW("Rwanda"),
SA("Saudi Arabia"), SB("Solomon Islands"), SC("Seychelles"), SD("Sudan"),
SE("Sweden"), SG("Singapore"), SH("Saint Helena"), SI("Slovenia"), SK("Slovakia"),
SL("Sierra Leone"), SM("San Marino"), SN("Senegal"), SO("Somalia"), SR("Suriname"),
SS("South Sudan"), ST("São Tomé and Príncipe"), SV("El Salvador"), SX("Sint Maarten"),
SY("Syria"), SZ("Eswatini"), TC("Turks and Caicos Islands"), TD("Chad"),
TF("French Southern Territories"), TG("Togo"), TH("Thailand"), TJ("Tajikistan"),
TK("Tokelau"), TL("Timor-Leste"), TM("Turkmenistan"), TN("Tunisia"), TO("Tonga"),
TR("Turkey"), TT("Trinidad and Tobago"), TV("Tuvalu"), TW("Taiwan"), TZ("Tanzania"),
UA("Ukraine"), UG("Uganda"), UM("United States Minor Outlying Islands"), US("United States"),
UY("Uruguay"), UZ("Uzbekistan"), VA("Vatican City"), VC("Saint Vincent and the Grenadines"),
VE("Venezuela"), VG("British Virgin Islands"), VI("U.S. Virgin Islands"), VN("Vietnam"),
VU("Vanuatu"), WF("Wallis and Futuna"), WS("Samoa"), YE("Yemen"), YT("Mayotte"),
ZA("South Africa"), ZM("Zambia"), ZW("Zimbabwe");
private final String countryName;
IsoCode(String countryName) {
this.countryName = countryName;
}
/**
* Converts a string to the corresponding IsoCode enum value.
*
@ -47,4 +93,8 @@ public enum IsoCode {
public String getCode() {
return name();
}
public String getFullName() {
return countryName;
}
}

View file

@ -1,33 +1,24 @@
package de.avatic.lcc.model.materials;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.model.packaging.PackagingListEntry;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
import java.util.Objects;
public class Material {
private Integer id;
@JsonProperty("part_number")
private String partNumber;
@JsonProperty("normalized_part_number")
private String normalizedPartNumber;
private String hsCode;
private String name;
@JsonProperty("is_deprecated")
private Boolean isDeprecated;
private MaterialPackaging packaging;
public Integer getId() {
return id;
}
@ -76,11 +67,27 @@ public class Material {
isDeprecated = deprecated;
}
public MaterialPackaging getPackaging() {
return packaging;
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
Material material = (Material) o;
return Objects.equals(id, material.id) && Objects.equals(partNumber, material.partNumber) && Objects.equals(normalizedPartNumber, material.normalizedPartNumber) && Objects.equals(hsCode, material.hsCode) && Objects.equals(name, material.name) && Objects.equals(isDeprecated, material.isDeprecated);
}
public void setPackaging(MaterialPackaging packaging) {
this.packaging = packaging;
@Override
public int hashCode() {
return Objects.hash(id, partNumber, normalizedPartNumber, hsCode, name, isDeprecated);
}
@Override
public String toString() {
return "Material{" +
"id=" + id +
", partNumber='" + partNumber + '\'' +
", normalizedPartNumber='" + normalizedPartNumber + '\'' +
", hsCode='" + hsCode + '\'' +
", name='" + name + '\'' +
", isDeprecated=" + isDeprecated +
'}';
}
}

View file

@ -1,8 +1,7 @@
package de.avatic.lcc.model.materials;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.model.nodes.NodeListEntry;
import de.avatic.lcc.model.packaging.PackagingDimension;
import de.avatic.lcc.dto.packaging.get.PackagingDimensionGetDTO;
public class MaterialPackaging {
@ -11,7 +10,7 @@ public class MaterialPackaging {
private MaterialSupplier supplier;
@JsonProperty("handling_unit")
private PackagingDimension hu;
private PackagingDimensionGetDTO hu;
public Integer getId() {
@ -30,11 +29,11 @@ public class MaterialPackaging {
this.supplier = supplier;
}
public PackagingDimension getHu() {
public PackagingDimensionGetDTO getHu() {
return hu;
}
public void setHu(PackagingDimension hu) {
public void setHu(PackagingDimensionGetDTO hu) {
this.hu = hu;
}
}

View file

@ -1,7 +1,7 @@
package de.avatic.lcc.model.materials;
import de.avatic.lcc.model.country.CountryListEntry;
import de.avatic.lcc.model.nodes.NodeType;
import de.avatic.lcc.dto.generic.NodeTypeDTO;
import java.util.List;
@ -11,7 +11,7 @@ public class MaterialSupplier {
private String name;
private CountryListEntry country;
private String address;
private List<NodeType> types;
private List<NodeTypeDTO> types;
public String getName() {
@ -46,11 +46,11 @@ public class MaterialSupplier {
this.address = address;
}
public List<NodeType> getTypes() {
public List<NodeTypeDTO> getTypes() {
return types;
}
public void setTypes(List<NodeType> types) {
public void setTypes(List<NodeTypeDTO> types) {
this.types = types;
}
}

View file

@ -1,23 +1,15 @@
package de.avatic.lcc.model.nodes;
import de.avatic.lcc.model.country.Country;
import jakarta.validation.constraints.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.MappedCollection;
import org.springframework.data.relational.core.mapping.Table;
import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@Table(name = "node")
public class Node {
@Id
private Integer id;
@NotNull
@ -45,28 +37,20 @@ public class Node {
@DecimalMax("90.0000")
private BigDecimal geoLat;
@Digits(integer = 7, fraction = 4)
@DecimalMin("-180.0000")
@DecimalMax("180.0000")
private BigDecimal geoLng;
@NotNull
private OffsetDateTime updatedAt;
@NotNull
private Boolean isDeprecated;
@Column("country_id")
@NotNull
private AggregateReference<Country,Integer> country;
private Integer countryId;
@MappedCollection(idColumn = "node_id", keyColumn = "sequence_number")
private List<NodePredecessor> nodePredecessors;
@MappedCollection(idColumn = "node_id")
private Set<OutboundCountryMapping> outboundCountryMapping;
private List<Integer> nodePredecessors;
private Collection<Integer> outboundCountries;
public Integer getId() {
return id;
@ -164,11 +148,27 @@ public class Node {
isDeprecated = deprecated;
}
public AggregateReference<Country, Integer> getCountry() {
return country;
public Integer getCountryId() {
return countryId;
}
public void setCountry(AggregateReference<Country, Integer> country) {
this.country = country;
public void setCountryId(Integer countryId) {
this.countryId = countryId;
}
public List<Integer> getNodePredecessors() {
return nodePredecessors;
}
public void setNodePredecessors(List<Integer> nodePredecessors) {
this.nodePredecessors = nodePredecessors;
}
public Collection<Integer> getOutboundCountries() {
return outboundCountries;
}
public void setOutboundCountries(Collection<Integer> outboundCountries) {
this.outboundCountries = outboundCountries;
}
}

View file

@ -1,5 +1,6 @@
package de.avatic.lcc.model.nodes;
import de.avatic.lcc.dto.generic.NodeTypeDTO;
import de.avatic.lcc.model.country.CountryListEntry;
import java.util.List;
@ -10,7 +11,7 @@ public class NodeListEntry {
private String name;
private CountryListEntry country;
private String address;
private List<NodeType> types;
private List<NodeTypeDTO> types;
public String getName() {
@ -45,11 +46,11 @@ public class NodeListEntry {
this.address = address;
}
public List<NodeType> getTypes() {
public List<NodeTypeDTO> getTypes() {
return types;
}
public void setTypes(List<NodeType> types) {
public void setTypes(List<NodeTypeDTO> types) {
this.types = types;
}
}

View file

@ -1,38 +1,17 @@
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;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.relational.core.mapping.MappedCollection;
import org.springframework.data.relational.core.mapping.Table;
import java.util.Set;
public class Packaging {
private Integer id;
@JsonProperty("is_deprecated")
private Boolean isDeprecated;
private PackagingSupplier supplier;
private Integer supplierId;
private PackagingMaterial material;
private Integer materialId;
@JsonProperty("handling_unit")
private PackagingDimension hu;
private Integer huId;
@JsonProperty("small_handling_unit")
private PackagingDimension shu;
private Integer shuId;
public Integer getId() {
return id;
@ -50,35 +29,35 @@ public class Packaging {
isDeprecated = deprecated;
}
public PackagingSupplier getSupplier() {
return supplier;
public Integer getSupplierId() {
return supplierId;
}
public void setSupplier(PackagingSupplier supplier) {
this.supplier = supplier;
public void setSupplierId(Integer supplierId) {
this.supplierId = supplierId;
}
public PackagingMaterial getMaterial() {
return material;
public Integer getMaterialId() {
return materialId;
}
public void setMaterial(PackagingMaterial material) {
this.material = material;
public void setMaterialId(Integer materialId) {
this.materialId = materialId;
}
public PackagingDimension getHu() {
return hu;
public Integer getHuId() {
return huId;
}
public void setHu(PackagingDimension hu) {
this.hu = hu;
public void setHuId(Integer huId) {
this.huId = huId;
}
public PackagingDimension getShu() {
return shu;
public Integer getShuId() {
return shuId;
}
public void setShu(PackagingDimension shu) {
this.shu = shu;
public void setShuId(Integer shuId) {
this.shuId = shuId;
}
}

View file

@ -1,41 +1,32 @@
package de.avatic.lcc.model.packaging;
import com.fasterxml.jackson.annotation.JsonProperty;
import de.avatic.lcc.model.utils.DimensionUnit;
import de.avatic.lcc.model.utils.WeightUnit;
public class PackagingDimension {
private Integer id;
private PackagingType type;
private Double length;
private Integer length;
private Double width;
private Integer width;
private Double height;
private Integer height;
@JsonProperty("dimension_unit")
private DimensionUnit dimensionUnit;
private Double weight;
private Integer 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;
}
@ -44,27 +35,35 @@ public class PackagingDimension {
this.id = id;
}
public Double getLength() {
public PackagingType getType() {
return type;
}
public void setType(PackagingType type) {
this.type = type;
}
public Integer getLength() {
return length;
}
public void setLength(Double length) {
public void setLength(Integer length) {
this.length = length;
}
public Double getWidth() {
public Integer getWidth() {
return width;
}
public void setWidth(Double width) {
public void setWidth(Integer width) {
this.width = width;
}
public Double getHeight() {
public Integer getHeight() {
return height;
}
public void setHeight(Double height) {
public void setHeight(Integer height) {
this.height = height;
}
@ -76,11 +75,11 @@ public class PackagingDimension {
this.dimensionUnit = dimensionUnit;
}
public Double getWeight() {
public Integer getWeight() {
return weight;
}
public void setWeight(Double weight) {
public void setWeight(Integer weight) {
this.weight = weight;
}

View file

@ -1,49 +0,0 @@
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 {
private Integer id;
private PackagingSupplier supplier;
private PackagingMaterial material;
@JsonProperty("handling_unit")
private PackagingDimension hu;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public PackagingSupplier getSupplier() {
return supplier;
}
public void setSupplier(PackagingSupplier supplier) {
this.supplier = supplier;
}
public PackagingMaterial getMaterial() {
return material;
}
public void setMaterial(PackagingMaterial material) {
this.material = material;
}
public PackagingDimension getHu() {
return hu;
}
public void setHu(PackagingDimension hu) {
this.hu = hu;
}
}

View file

@ -1,6 +1,8 @@
package de.avatic.lcc.model.packaging;
import de.avatic.lcc.dto.packaging.get.PackagingDimensionGetDTO;
/**
* Represents the type of packaging used in the system.
* This enum defines two types of packaging:
@ -9,7 +11,7 @@ package de.avatic.lcc.model.packaging;
* - HU: Handling Unit.
*
* It is commonly utilized in packaging-related entities such as
* {@link PackagingDimension} to specify the type
* {@link PackagingDimensionGetDTO} to specify the type
* of a particular packaging instance.
*/
public enum PackagingType {

View file

@ -2,9 +2,9 @@ package de.avatic.lcc.model.premisses;
import de.avatic.lcc.model.materials.Material;
import de.avatic.lcc.model.nodes.Node;
import de.avatic.lcc.model.packaging.DimensionUnit;
import de.avatic.lcc.model.packaging.Packaging;
import de.avatic.lcc.model.packaging.WeightUnit;
import de.avatic.lcc.model.utils.DimensionUnit;
import de.avatic.lcc.dto.packaging.get.PackagingGetDTO;
import de.avatic.lcc.model.utils.WeightUnit;
import de.avatic.lcc.model.user.SysUser;
import jakarta.validation.constraints.Digits;
import jakarta.validation.constraints.NotNull;
@ -89,7 +89,7 @@ public class Premiss {
private AggregateReference<Node, Integer> userSupplierNode;
@Column("packaging_id")
private AggregateReference<Packaging, Integer> packaging;
private AggregateReference<PackagingGetDTO, Integer> packaging;
@NotNull
private AggregateReference<SysUser, Integer> user;
@ -273,11 +273,11 @@ public class Premiss {
this.userSupplierNode = userSupplierNode;
}
public AggregateReference<Packaging, Integer> getPackaging() {
public AggregateReference<PackagingGetDTO, Integer> getPackaging() {
return packaging;
}
public void setPackaging(AggregateReference<Packaging, Integer> packaging) {
public void setPackaging(AggregateReference<PackagingGetDTO, Integer> packaging) {
this.packaging = packaging;
}

View file

@ -7,39 +7,38 @@ import org.springframework.data.jdbc.core.mapping.AggregateReference;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@Table(name = "country_property")
public class CountryProperty {
@Id
private Integer id;
@Size(max = 500)
private String propertyValue;
private String activeValue;
@Column("country_property_type")
private AggregateReference<CountryPropertyType, Integer> type;
private String draftValue;
public Integer getId() {
return id;
private CountryPropertyType type;
public String getActiveValue() {
return activeValue;
}
public void setId(Integer id) {
this.id = id;
public void setActiveValue(String activeValue) {
this.activeValue = activeValue;
}
public String getPropertyValue() {
return propertyValue;
public String getDraftValue() {
return draftValue;
}
public void setPropertyValue(String propertyValue) {
this.propertyValue = propertyValue;
public void setDraftValue(String draftValue) {
this.draftValue = draftValue;
}
public AggregateReference<CountryPropertyType, Integer> getType() {
public CountryPropertyType getType() {
return type;
}
public void setType(AggregateReference<CountryPropertyType, Integer> type) {
public void setType(CountryPropertyType type) {
this.type = type;
}
}

View file

@ -6,10 +6,10 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Table("country_property_type")
public class CountryPropertyType {
@Id
private Integer id;
@NotNull

View file

@ -1,4 +1,4 @@
package de.avatic.lcc.model.packaging;
package de.avatic.lcc.model.utils;
import com.fasterxml.jackson.annotation.JsonValue;
@ -32,6 +32,10 @@ public enum DimensionUnit {
return displayedName;
}
public Number convertToMM(Number value) {
return DimensionUnit.MM.convertFrom(value, this).intValue();
}
/**
* Converts a value from one dimension unit to this unit.
*
@ -40,7 +44,7 @@ public enum DimensionUnit {
* @return the converted value
* @throws IllegalArgumentException if value or fromUnit is null
*/
public Double convertFrom(Number value, DimensionUnit fromUnit) {
public Number convertFrom(Number value, DimensionUnit fromUnit) {
if (value == null || fromUnit == null) {
throw new IllegalArgumentException("Value and fromUnit must not be null");
}
@ -59,7 +63,7 @@ public enum DimensionUnit {
* @return the converted value in the target unit
* @throws IllegalArgumentException if the provided value is null
*/
public Double convertFromMM(Number value) {
public Number convertFromMM(Number value) {
return convertFrom(value, MM);
}
}

View file

@ -1,4 +1,4 @@
package de.avatic.lcc.model.packaging;
package de.avatic.lcc.model.utils;
import com.fasterxml.jackson.annotation.JsonValue;
@ -38,7 +38,7 @@ public enum WeightUnit {
* @return the converted value
* @throws IllegalArgumentException if value or fromUnit is null
*/
public Double convertFrom(Number value, WeightUnit fromUnit) {
public Number convertFrom(Number value, WeightUnit fromUnit) {
if (value == null || fromUnit == null) {
throw new IllegalArgumentException("Value and fromUnit must not be null");
}
@ -50,7 +50,11 @@ public enum WeightUnit {
return valueInBaseUnit / this.baseFactor;
}
public Double convertFromG(Number value) {
public Number convertFromG(Number value) {
return convertFrom(value, G);
}
public Number convertToG(Double weight) {
return WeightUnit.G.convertFrom(weight, this);
}
}

View file

@ -0,0 +1,4 @@
package de.avatic.lcc.repositories;
public class ContainerRateRepository {
}

View file

@ -1,25 +1,20 @@
package de.avatic.lcc.repositories;
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.materials.MaterialPackaging;
import de.avatic.lcc.model.materials.MaterialSupplier;
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.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Optional;
@ -33,137 +28,85 @@ public class MaterialRepository {
this.jdbcTemplate = jdbcTemplate;
}
@Transactional
public SearchQueryResult<MaterialListEntry> listMaterials(String filter, boolean excludeDeprecated, SearchQueryPagination pagination) {
String query = "SELECT id, name, part_number FROM material WHERE name LIKE ? OR part_number LIKE ? LIMIT ? OFFSET ?";
var materials = jdbcTemplate.query(query, (rs, rowNum) -> {
MaterialListEntry data = new MaterialListEntry();
data.setId(rs.getInt("id"));
data.setName(rs.getString("name"));
data.setPartNumber(rs.getString("part_number"));
return data;
}, "%" + filter + "%", "%" + filter + "%", pagination.getLimit(), pagination.getOffset());
private static class MaterialMapper implements RowMapper<Material> {
Integer totalCount = jdbcTemplate.queryForObject(
"SELECT COUNT(*) FROM material WHERE name LIKE ? OR part_number LIKE ?",
Integer.class, "%" + filter + "%", "%" + filter + "%"
);
return new SearchQueryResult<>(materials, totalCount, pagination.getLimit(), pagination.getOffset());
}
@Transactional
public Optional<Material> getById(Integer id) {
String query = "SELECT * FROM material WHERE id = ? AND is_deprecated = FALSE";
Material material = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
@Override
public Material mapRow(ResultSet rs, int rowNum) throws SQLException {
Material data = new Material();
data.setId(rs.getInt("id"));
data.setName(rs.getString("name"));
data.setPartNumber(rs.getString("part_number"));
data.setNormalizedPartNumber(rs.getString("normalized_part_number"));
data.setHsCode(rs.getString("hs_code"));
data.setDeprecated(rs.getBoolean("is_deprecated"));
data.setPackaging(getMaterialPackaging(rs.getInt("id")).orElse(null));
return data;
}, id);
}
}
private static String buildCountQuery(String filter, boolean excludeDeprecated) {
StringBuilder queryBuilder = new StringBuilder("""
SELECT count(*)
FROM material WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
}
if (filter != null) {
queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ?) ");
}
return queryBuilder.toString();
}
private static String buildQuery(String filter, boolean excludeDeprecated) {
StringBuilder queryBuilder = new StringBuilder("""
SELECT id, name, part_number, normalized_part_number, hs_code, is_deprecated
FROM material WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
}
if (filter != null) {
queryBuilder.append(" AND (name LIKE ? OR part_number LIKE ?) ");
}
queryBuilder.append(" LIMIT ? OFFSET ?");
return queryBuilder.toString();
}
@Transactional
public Optional<Integer> setDeprecatedById(Integer id) {
String query = "UPDATE material SET is_deprecated = TRUE WHERE id = ?";
return Optional.ofNullable(jdbcTemplate.update(query, id) == 0 ? null : id);
}
@Transactional
public SearchQueryResult<Material> listMaterials(String filter, boolean excludeDeprecated, SearchQueryPagination pagination) {
String query = buildQuery(filter, excludeDeprecated);
var materials = jdbcTemplate.query(query, new MaterialMapper(),
"%" + filter + "%", "%" + filter + "%", !excludeDeprecated, pagination.getLimit(), pagination.getOffset());
Integer totalCount = jdbcTemplate.queryForObject(
buildCountQuery(filter, excludeDeprecated),
Integer.class, "%" + filter + "%", "%" + filter + "%", !excludeDeprecated
);
return new SearchQueryResult<>(materials, pagination.getPage(), totalCount, pagination.getLimit());
}
@Transactional
public Optional<Material> getById(Integer id) {
String query = "SELECT * FROM material WHERE id = ? AND is_deprecated = FALSE";
Material material = jdbcTemplate.queryForObject(query, new MaterialMapper(), id);
return Optional.ofNullable(material);
}
public Optional<MaterialPackaging> getMaterialPackaging(Integer id) {
String query = """
SELECT id
FROM packaging
WHERE id = ?""";
MaterialPackaging packaging = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
MaterialPackaging data = new MaterialPackaging();
data.setId(rs.getInt("id"));
data.setHu(getPackagingDimensionById(rs.getInt("hu_dimension_id")).orElse(null) );
data.setSupplier(getMaterialSupplier(rs.getInt("supplier_node_id")).orElse(null) );
return data;
}, id);
return Optional.ofNullable(packaging);
}
private Optional<PackagingDimension> getPackagingDimensionById(int 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);
}
private Optional<MaterialSupplier> getMaterialSupplier(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 MaterialSupplier();
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 void deleteById(Integer id) {
String deleteQuery = "UPDATE material SET is_deprecated = TRUE WHERE id = ?";
@ -198,4 +141,5 @@ public class MaterialRepository {
: null);
}
}

View file

@ -0,0 +1,69 @@
package de.avatic.lcc.repositories;
import de.avatic.lcc.model.nodes.Node;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
@Repository
public class NodeRepository {
private final JdbcTemplate jdbcTemplate;
public NodeRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Transactional
public Optional<Node> getById(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, node.country_id as country_id, node.predecessor_required as predecessor_required
FROM node
WHERE node.id = ?""";
var node = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
var data = new Node();
data.setId(rs.getInt("id"));
data.setName(rs.getString("name"));
data.setAddress(rs.getString("address"));
data.setCountryId(rs.getInt("country_id"));
data.setSink(rs.getBoolean("is_sink"));
data.setSource(rs.getBoolean("is_source"));
data.setIntermediate(rs.getBoolean("is_intermediate"));
data.setPredecessorRequired(rs.getBoolean("predecessor_required"));
data.setNodePredecessors(getPredecessorsOf(data.getId()));
return data;
}, id);
return Optional.ofNullable(node);
}
private List<Integer> getPredecessorsOf(Integer id) {
String query = """
SELECT node_predecessor.predecessor_node_id
FROM node_predecessor
WHERE node_predecessor.node_id = ? ORDER BY node_predecessor.sequence_number""";
return jdbcTemplate.queryForList(query, Integer.class, id);
}
private Collection<Integer> getOutboundCountriesOf(Integer id) {
String query = """
SELECT outbound_country_mapping.country_id
FROM outbound_country_mapping
WHERE outbound_country_mapping.node_id = ?""";
return jdbcTemplate.queryForList(query, Integer.class, id);
}
}

View file

@ -1,224 +0,0 @@
package de.avatic.lcc.repositories;
import de.avatic.lcc.model.country.CountryListEntry;
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.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
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 packaging = 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(getPackagingSupplierById(rs.getInt("supplier_node_id")).orElse(null) );
return data;
}, params.toArray());
return new SearchQueryResult<>(packaging, 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(getPackagingSupplierById(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<PackagingMaterial> 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 PackagingMaterial();
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<PackagingSupplier> getPackagingSupplierById(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 PackagingSupplier();
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();
}
}

View file

@ -0,0 +1,56 @@
package de.avatic.lcc.repositories.country;
import de.avatic.lcc.model.properties.CountryProperty;
import de.avatic.lcc.model.properties.CountryPropertyType;
import de.avatic.lcc.model.properties.PropertyDataType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CountryPropertyRepository {
private final JdbcTemplate jdbcTemplate;
public CountryPropertyRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<CountryProperty> listByCountryId(Integer id) {
String query = """
SELECT draft.id AS draft_id, active.id AS active_id, active.property_value AS avtice_value, draft.property_value AS draft_value,
type.id AS type_id, type.name AS name, type.data_type AS data_type, type.is_required AS is_required,
type.external_mapping_id AS external_mapping_id, type.validation_rule AS validation_rule
FROM country_property active
LEFT JOIN country_property_type type on active.country_property_type_id = type.id
LEFT JOIN country_property draft on active.id = draft.id
LEFT JOIN property_set active_set on active.property_set_id = active_set.id
LEFT JOIN property_set draft_set on draft.property_set_id = draft_set.id
WHERE active.country_id = ? AND active_set.state = 'VALID' AND draft_set.state = 'DRAFT'""";
return jdbcTemplate.query(query, (rs, rowNum) -> {
CountryProperty entity = new CountryProperty();
CountryPropertyType type = new CountryPropertyType();
int idActive = rs.getInt("active_id");
int idDraft = rs.getInt("draft_id");
type.setId(rs.getInt("type_id"));
type.setName(rs.getString("name"));
type.setDataType(PropertyDataType.valueOf(rs.getString("data_type")));
type.setRequired(rs.getBoolean("is_required"));
type.setExternalMappingId(rs.getString("external_mapping_id"));
type.setValidationRule(rs.getString("validation_rule"));
entity.setActiveValue(rs.getString("active_value"));
entity.setDraftValue(rs.getString("draft_value"));
entity.setType(type);
return entity;
}, id);
}
}

View file

@ -0,0 +1,107 @@
package de.avatic.lcc.repositories.country;
import de.avatic.lcc.model.country.Country;
import de.avatic.lcc.model.country.IsoCode;
import de.avatic.lcc.model.country.RegionCode;
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.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;
@Repository
public class CountryRepository {
private final JdbcTemplate jdbcTemplate;
public CountryRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Transactional
public Optional<Country> getById(Integer countryId) {
String query = """
SELECT country.id AS id, country.iso_code AS iso_code, country.region_code AS region_code, country.is_deprecated AS is_deprecated
FROM country
WHERE country.id = ?
""";
var country = jdbcTemplate.queryForObject(query, (rs, rowNum) -> {
var data = new Country();
data.setId(rs.getInt("id"));
data.setIsoCode(IsoCode.valueOf(rs.getString("iso_code")));
data.setRegionCode(RegionCode.valueOf(rs.getString("region_code")));
data.setDeprecated(rs.getBoolean("is_deprecated"));
return data;
});
return Optional.ofNullable(country);
}
public SearchQueryResult<Country> listCountries(String filter, boolean excludeDeprecated, SearchQueryPagination pagination) {
String query = buildQuery(filter, excludeDeprecated);
var countries = jdbcTemplate.query(query, new CountryMapper(),
"%" + filter + "%", "%" + filter + "%", !excludeDeprecated, pagination.getLimit(), pagination.getOffset());
Integer totalCount = jdbcTemplate.queryForObject(
buildCountQuery(filter, excludeDeprecated),
Integer.class, "%" + filter + "%", "%" + filter + "%", !excludeDeprecated
);
return new SearchQueryResult<>(countries, pagination.getPage(), totalCount, pagination.getLimit());
}
private String buildCountQuery(String filter, boolean excludeDeprecated) {
StringBuilder queryBuilder = new StringBuilder("""
SELECT COUNT(*)
FROM WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
}
if (filter != null) {
queryBuilder.append(" AND (iso_code LIKE ? OR region_code LIKE ?) ");
}
return queryBuilder.toString();
}
private String buildQuery(String filter, boolean excludeDeprecated) {
StringBuilder queryBuilder = new StringBuilder("""
SELECT id, iso_code, region_code, is_deprecated
FROM WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
}
if (filter != null) {
queryBuilder.append(" AND (iso_code LIKE ? OR region_code LIKE ?) ");
}
queryBuilder.append(" LIMIT ? OFFSET ?");
return queryBuilder.toString();
}
private static class CountryMapper implements RowMapper<Country> {
@Override
public Country mapRow(ResultSet rs, int rowNum) throws SQLException {
Country entity = new Country();
entity.setId(rs.getInt("id"));
entity.setIsoCode(IsoCode.valueOf(rs.getString("iso_code")));
entity.setRegionCode(RegionCode.valueOf(rs.getString("region_code")));
return entity;
}
}
}

View file

@ -0,0 +1,113 @@
package de.avatic.lcc.repositories.packaging;
import de.avatic.lcc.model.packaging.PackagingDimension;
import de.avatic.lcc.model.packaging.PackagingType;
import de.avatic.lcc.model.utils.DimensionUnit;
import de.avatic.lcc.model.utils.WeightUnit;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Objects;
import java.util.Optional;
@Repository
public class PackagingDimensionRepository {
private final JdbcTemplate jdbcTemplate;
public PackagingDimensionRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Transactional
public Optional<PackagingDimension> getById(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 entity = new PackagingDimension();
entity.setId(rs.getInt("id"));
entity.setDimensionUnit(DimensionUnit.valueOf(rs.getString("displayed_dimension_unit")));
entity.setWeightUnit(WeightUnit.valueOf(rs.getString("displayed_weight_unit")));
entity.setType(PackagingType.valueOf(rs.getString("type")));
entity.setDeprecated(rs.getBoolean("is_deprecated"));
entity.setWeight(rs.getInt("weight"));
entity.setWidth(rs.getInt("width"));
entity.setHeight(rs.getInt("height"));
entity.setLength(rs.getInt("length"));
return entity;
}, id);
return Optional.ofNullable(dimension);
}
public void update(PackagingDimension dimension) {
DimensionUnit shuDimensionUnit = dimension.getDimensionUnit();
WeightUnit shuWeightUnit = dimension.getWeightUnit();
String huQuery = """
UPDATE packaging_dimension SET type = ?, width = ?, length = ?, height = ?, weight = ?,
displayed_dimension_unit = ?, displayed_weight_unit = ?, content_unit_count = ?,
is_deprecated = ? WHERE id = ?""";
jdbcTemplate.update(huQuery,
dimension.getType().name(),
dimension.getWidth(),
dimension.getLength(),
dimension.getHeight(),
dimension.getWeight(),
dimension.getDimensionUnit().name(),
dimension.getWeightUnit().name(),
dimension.getContentUnitCount(),
dimension.getDeprecated(),
dimension.getId());
}
public Optional<Integer> insert(PackagingDimension entity) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection
.prepareStatement("INSERT INTO packaging_dimension (type, length, width, height, displayed_dimension_unit, weight, displayed_weight_unit, content_unit_count, is_deprecated) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
Statement.RETURN_GENERATED_KEYS);
ps.setString(1, entity.getType().name()); //
ps.setInt(2, entity.getLength());
ps.setInt(3, entity.getWidth());
ps.setInt(4, entity.getHeight());
ps.setString(5, entity.getDimensionUnit().name());
ps.setInt(6, entity.getWeight());
ps.setString(7, entity.getWeightUnit().name());
ps.setInt(8, entity.getContentUnitCount());
ps.setBoolean(9, entity.getDeprecated());
return ps;
}, keyHolder);
return Optional.ofNullable(!Objects.requireNonNull(keyHolder.getKeys()).isEmpty() ? ((Integer) keyHolder.getKeys().values().iterator().next())
: null);
}
public Optional<Integer> setDeprecatedById(Integer id) {
String query = "UPDATE packaging_dimension SET is_deprecated = TRUE WHERE id = ?";
return Optional.ofNullable(jdbcTemplate.update(query, id) == 0 ? null : id);
}
}

View file

@ -0,0 +1,7 @@
package de.avatic.lcc.repositories.packaging;
import org.springframework.stereotype.Repository;
@Repository
public class PackagingPropertyRepository {
}

View file

@ -0,0 +1,178 @@
package de.avatic.lcc.repositories.packaging;
import de.avatic.lcc.model.packaging.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.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Repository
public class PackagingRepository {
private static class PackagingMapper implements RowMapper<Packaging> {
@Override
public Packaging mapRow(ResultSet rs, int rowNum) throws SQLException {
Packaging data = new Packaging();
data.setId(rs.getInt("id"));
data.setHuId(rs.getInt("hu_dimension_id"));
data.setShuId(rs.getInt("shu_dimension_id"));
data.setMaterialId(rs.getInt("material_id"));
data.setSupplierId(rs.getInt("supplier_node_id"));
data.setDeprecated(rs.getBoolean("is_deprecated"));
return data;
}
}
private final JdbcTemplate jdbcTemplate;
public PackagingRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Transactional
public SearchQueryResult<Packaging> listPackaging(Integer materialId, Integer supplierId, boolean excludeDeprecated, SearchQueryPagination pagination) {
String query = buildQuery(materialId, supplierId, excludeDeprecated);
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 packaging = jdbcTemplate.query(query, new PackagingMapper(), params.toArray());
return new SearchQueryResult<>(packaging, pagination.getPage(), countPackaging(materialId, supplierId, excludeDeprecated), pagination.getLimit());
}
private static String buildQuery(Integer materialId, Integer supplierId, boolean excludeDeprecated) {
StringBuilder queryBuilder = new StringBuilder("""
SELECT id,
FROM packaging
WHERE 1=1""");
if (excludeDeprecated) {
queryBuilder.append(" AND is_deprecated = FALSE");
}
if (materialId != null) {
queryBuilder.append(" AND material_id = ?");
}
if (supplierId != null) {
queryBuilder.append(" AND supplier_node_id = ?");
}
queryBuilder.append(" LIMIT ? OFFSET ?");
return queryBuilder.toString();
}
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 entity = jdbcTemplate.queryForObject(query, new PackagingMapper(), id);
return Optional.ofNullable(entity);
}
@Transactional
public void update(Packaging packaging) {
String query = "UPDATE packaging SET is_deprecated = ?, supplier_node_id = ?, material_id = ?, hu_dimension_id = ?, shu_dimension_id = ? WHERE id = ?";
jdbcTemplate.update(query,
packaging.getDeprecated(),
packaging.getSupplierId(),
packaging.getMaterialId(),
packaging.getHuId(),
packaging.getShuId(),
packaging.getId());
}
@Transactional
public Optional<Integer> setDeprecatedById(Integer id) {
String query = "UPDATE packaging SET is_deprecated = TRUE WHERE id = ?";
return Optional.ofNullable(jdbcTemplate.update(query, id) == 0 ? null : id);
}
@Transactional
public Optional<Integer> insert(Packaging entity) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection
.prepareStatement("INSERT INTO packaging (supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated) VALUES (?, ?, ?, ?, ?)",
Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, entity.getSupplierId()); //
ps.setInt(2, entity.getMaterialId());
ps.setInt(3, entity.getHuId());
ps.setInt(4, entity.getShuId());
ps.setBoolean(5, entity.getDeprecated());
return ps;
}, keyHolder);
return Optional.ofNullable(!Objects.requireNonNull(keyHolder.getKeys()).isEmpty() ? ((Integer) keyHolder.getKeys().values().iterator().next())
: null);
}
public List<Packaging> getByMaterialId(Integer materialId) {
String query = """
SELECT id, supplier_node_id, material_id, hu_dimension_id, shu_dimension_id, is_deprecated
FROM packaging
WHERE packaging.material_id = ?""";
return jdbcTemplate.query(query, new PackagingMapper(), materialId);
}
}

View file

@ -18,4 +18,6 @@ public class SearchQueryPagination {
return page * size;
}
public Integer getPage() { return page; }
}

View file

@ -15,21 +15,22 @@ public class SearchQueryResult<T> {
private List<T> result;
private Integer page, totalPages, totalElements;
private final Integer page, totalPages, totalElements, elementsPerPage;
/**
* 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.
* @param result The list of results for the query.
* @param page The current page number (0-indexed).
* @param totalElements The total number of elements across all pages.
* @param elementsPerPage Elements on one page.
*/
public SearchQueryResult(List<T> result, Integer page, Integer totalPages, Integer totalElements) {
public SearchQueryResult(List<T> result, Integer page, Integer totalElements, Integer elementsPerPage) {
this.result = result;
this.page = page;
this.totalPages = totalPages;
this.totalPages = totalElements/elementsPerPage + (totalElements%elementsPerPage == 0 ? 0 : 1);
this.totalElements = totalElements;
this.elementsPerPage = elementsPerPage;
}
/**
@ -41,14 +42,6 @@ public class SearchQueryResult<T> {
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).
@ -59,14 +52,6 @@ public class SearchQueryResult<T> {
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.
@ -77,15 +62,6 @@ public class SearchQueryResult<T> {
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.
*
@ -95,12 +71,7 @@ public class SearchQueryResult<T> {
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;
public Integer getElementsPerPage() {
return elementsPerPage;
}
}

View file

@ -1,16 +0,0 @@
package de.avatic.lcc.repositories.utils;
public class UnitConverter {
public static double convert(Integer value, String unit) {
return switch (unit) {
case "MM", "G" -> Math.round(value * 100.0) / 100.0;
case "CM" -> Math.round((value / 10.0) * 100.0) / 100.0;
case "M", "KG" -> Math.round((value / 1000.0) * 100.0) / 100.0;
case "T" -> Math.round((value / 1000000.0) * 100.0) / 100.0;
default -> throw new IllegalArgumentException("Unknown unit: " + unit);
};
}
}

View file

@ -0,0 +1,52 @@
package de.avatic.lcc.service;
import de.avatic.lcc.dto.countries.get.CountryGetDTO;
import de.avatic.lcc.dto.countries.get.CountryListGetDTO;
import de.avatic.lcc.model.country.Country;
import de.avatic.lcc.model.properties.CountryProperty;
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
import de.avatic.lcc.repositories.country.CountryRepository;
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.transformer.CountryTransformerService;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CountryService {
private final CountryRepository countryRepository;
private final CountryTransformerService countryTransformerService;
private final CountryPropertyRepository countryPropertyRepository;
public CountryService(CountryRepository countryRepository, CountryTransformerService countryTransformerService, CountryPropertyRepository countryPropertyRepository) {
this.countryRepository = countryRepository;
this.countryTransformerService = countryTransformerService;
this.countryPropertyRepository = countryPropertyRepository;
}
public SearchQueryResult<CountryListGetDTO> listMaterial(String filter, int page, int limit) {
SearchQueryResult<Country> queryResult = countryRepository.listCountries(filter, true, new SearchQueryPagination(page, limit));
List<CountryListGetDTO> dto = queryResult.toList().stream().map(country -> {
CountryListGetDTO dtoEntry = new CountryListGetDTO();
dtoEntry.setId(country.getId());
dtoEntry.setIsoCode(country.getIsoCode().getCode());
dtoEntry.setName(country.getIsoCode().getFullName());
dtoEntry.setRegionCode(country.getRegionCode().getCode());
return dtoEntry;
}).toList();
return new SearchQueryResult<>(dto, queryResult.getPage(), queryResult.getTotalElements(), queryResult.getElementsPerPage() );
}
public CountryGetDTO getCountry(Integer id) {
List<CountryProperty> properties = countryPropertyRepository.listByCountryId(id);
return countryTransformerService.convertToCountryGetDTO(countryRepository.getById(id), properties).orElseThrow();
}
}

View file

@ -1,46 +1,80 @@
package de.avatic.lcc.service;
import de.avatic.lcc.dto.material.get.MaterialGetDTO;
import de.avatic.lcc.dto.material.get.MaterialPackagingGetDTO;
import de.avatic.lcc.dto.material.post.MaterialPostDTO;
import de.avatic.lcc.model.country.Country;
import de.avatic.lcc.model.materials.Material;
import de.avatic.lcc.model.materials.MaterialListEntry;
import de.avatic.lcc.dto.material.get.MaterialListGetDTO;
import de.avatic.lcc.model.nodes.Node;
import de.avatic.lcc.model.packaging.PackagingDimension;
import de.avatic.lcc.repositories.country.CountryRepository;
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.PackagingRepository;
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.transformer.MaterialTransformerService;
import de.avatic.lcc.util.Check;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class MaterialService {
MaterialRepository materialRepository;
private final MaterialTransformerService materialTransformerService;
private final PackagingRepository packagingRepository;
private final CountryRepository countryRepository;
private final NodeRepository nodeRepository;
private final PackagingDimensionRepository packagingDimensionRepository;
private final MaterialRepository materialRepository;
public MaterialService(MaterialRepository materialRepository) {
public MaterialService(MaterialRepository materialRepository, MaterialTransformerService materialTransformerService, PackagingRepository packagingRepository, CountryRepository countryRepository, NodeRepository nodeRepository, PackagingDimensionRepository packagingDimensionRepository) {
this.materialRepository = materialRepository;
this.materialTransformerService = materialTransformerService;
this.packagingRepository = packagingRepository;
this.countryRepository = countryRepository;
this.nodeRepository = nodeRepository;
this.packagingDimensionRepository = packagingDimensionRepository;
}
public Material updateMaterial(Integer id, Material material) {
material.setId(id);
material.setNormalizedPartNumber(normalizePartNumber(material.getPartNumber()));
return materialRepository.update(material);
public SearchQueryResult<MaterialListGetDTO> listMaterial(String filter, int page, int limit) {
SearchQueryResult<Material> queryResult = materialRepository.listMaterials(filter, true, new SearchQueryPagination(page, limit));
List<MaterialListGetDTO> dto = queryResult.toList().stream().map(materialTransformerService::convertToMaterialListGetDTO).toList();
return new SearchQueryResult<>(dto, queryResult.getPage(), queryResult.getTotalElements(), queryResult.getElementsPerPage());
}
private String normalizePartNumber(String partNumber) {
if(partNumber.length() > 12) throw new IllegalArgumentException("Part number must be less than 12 characters");
return "000000000000".concat(partNumber).substring(partNumber.length());
public MaterialGetDTO getMaterial(Integer id) {
List<MaterialPackagingGetDTO> packaging = packagingRepository.getByMaterialId(id).stream().map(p -> {
Optional<Node> supplier = nodeRepository.getById(p.getSupplierId());
Optional<Country> country = countryRepository.getById(supplier.orElseThrow().getCountryId());
Optional<PackagingDimension> hu = packagingDimensionRepository.getById(p.getHuId());
Optional<PackagingDimension> shu = packagingDimensionRepository.getById(p.getShuId());
return materialTransformerService.convertToMaterialPackagingGetDTO(p, supplier, country, hu, shu);
}).toList();
return materialTransformerService.convertToMaterialGetDTO(materialRepository.getById(id)).orElseThrow(() -> new RuntimeException("Material not found with id " + id));
}
public Material getMaterial(Integer id) {
return materialRepository.getById(id).orElseThrow(() -> new RuntimeException("Material not found with id " + id));
public void updateMaterial(Integer id, MaterialPostDTO dto) {
//check consistency
Check.equals(id, dto.getId());
materialRepository.update(materialTransformerService.convertFromMaterialPostDTO(dto));
}
public Integer createMaterial(Material material) {
material.setNormalizedPartNumber(normalizePartNumber(material.getPartNumber()));
return materialRepository.create(material).orElseThrow(() -> new RuntimeException("Unable to create Material " + material));
public Integer createMaterial(MaterialPostDTO dto) {
return materialRepository.create(materialTransformerService.convertFromMaterialPostDTO(dto)).orElseThrow(() -> new RuntimeException("Unable to create Material " + dto));
}
public SearchQueryResult<MaterialListEntry> listMaterials(String filter, int page, int limit) {
return materialRepository.listMaterials(filter, new SearchQueryPagination(page, limit));
}
public Integer deleteMaterial(Integer id) {
return materialRepository.setDeprecatedById(id).orElseThrow(() -> new RuntimeException("Packaging does not exists " + id));
public void deleteMaterial(Integer id) {
materialRepository.deleteById(id);
}
}

View file

@ -1,39 +1,115 @@
package de.avatic.lcc.service;
import de.avatic.lcc.dto.packaging.get.PackagingGetDTO;
import de.avatic.lcc.dto.packaging.post.PackagingPostDTO;
import de.avatic.lcc.model.country.Country;
import de.avatic.lcc.model.materials.Material;
import de.avatic.lcc.model.nodes.Node;
import de.avatic.lcc.model.packaging.Packaging;
import de.avatic.lcc.model.packaging.PackagingListEntry;
import de.avatic.lcc.repositories.PackagingRepository;
import de.avatic.lcc.model.packaging.PackagingDimension;
import de.avatic.lcc.repositories.country.CountryRepository;
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.PackagingRepository;
import de.avatic.lcc.repositories.pagination.SearchQueryPagination;
import de.avatic.lcc.repositories.pagination.SearchQueryResult;
import de.avatic.lcc.service.transformer.DimensionTransformerService;
import de.avatic.lcc.service.transformer.NodeTransformerService;
import de.avatic.lcc.service.transformer.PackagingTransformerService;
import de.avatic.lcc.util.Check;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
public class PackagingService {
private final PackagingRepository packagingRepository;
private final PackagingDimensionRepository packagingDimensionRepository;
private final NodeRepository nodeRepository;
private final MaterialRepository materialRepository;
private final CountryRepository countryRepository;
private final PackagingTransformerService packagingTransformerService;
public PackagingService(PackagingRepository packagingRepository) {
public PackagingService(PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, NodeRepository nodeRepository, MaterialRepository materialRepository, DimensionTransformerService dimensionTransformerService, NodeTransformerService nodeTransformerService, CountryRepository countryRepository, PackagingTransformerService packagingTransformerService) {
this.packagingRepository = packagingRepository;
this.packagingDimensionRepository = packagingDimensionRepository;
this.nodeRepository = nodeRepository;
this.materialRepository = materialRepository;
this.countryRepository = countryRepository;
this.packagingTransformerService = packagingTransformerService;
}
public SearchQueryResult<PackagingListEntry> listPackaging(Integer materialId, Integer supplierId, int page, int limit) {
return packagingRepository.listPackaging(materialId, supplierId, true, new SearchQueryPagination(page, limit));
@Transactional
public SearchQueryResult<PackagingGetDTO> listPackaging(Integer materialId, Integer supplierId, int page, int limit) {
SearchQueryResult<Packaging> queryResult = packagingRepository.listPackaging(materialId, supplierId, true, new SearchQueryPagination(page, limit));
List<PackagingGetDTO> dto = queryResult.toList().stream().map(packaging -> {
PackagingGetDTO dtoEntry = new PackagingGetDTO();
Optional<Node> node = nodeRepository.getById(packaging.getSupplierId());
Optional<Country> country = countryRepository.getById(node.orElseThrow().getCountryId());
Optional<Material> material = materialRepository.getById(packaging.getMaterialId());
dtoEntry.setHu(packagingTransformerService.convertToPackagingDimensionDTO(packagingDimensionRepository.getById(packaging.getHuId())).orElseThrow());
dtoEntry.setShu(packagingTransformerService.convertToPackagingDimensionDTO(packagingDimensionRepository.getById(packaging.getShuId())).orElseThrow());
dtoEntry.setSupplier(packagingTransformerService.convertToPackagingSupplierDTO(node, country).orElseThrow());
dtoEntry.setMaterial(packagingTransformerService.convertToPackagingMaterialDTO(material).orElseThrow());
return dtoEntry;
}).toList();
return new SearchQueryResult<>(dto, queryResult.getPage(), queryResult.getTotalElements(), queryResult.getElementsPerPage() );
}
@Transactional
public PackagingGetDTO getPackaging(Integer id) {
public void updatePackaging(Integer id, Packaging packaging) {
packaging.setId(id);
packagingRepository.update(packaging);
Optional<Packaging> packaging = packagingRepository.getById(id);
Optional<Material> material = materialRepository.getById(packaging.orElseThrow().getMaterialId());
Optional<Node> supplier = nodeRepository.getById(packaging.orElseThrow().getSupplierId());
Optional<Country> country = countryRepository.getById(supplier.orElseThrow().getCountryId());
Optional<PackagingDimension> hu = packagingDimensionRepository.getById(packaging.orElseThrow().getHuId());
Optional<PackagingDimension> shu = packagingDimensionRepository.getById(packaging.orElseThrow().getShuId());
//TODO packaging properties.
return packagingTransformerService.convertToPackagingGetDTO(packaging, material, supplier, country, hu, shu).orElseThrow();
}
@Transactional
public void updatePackaging(Integer id, PackagingPostDTO dto) {
Optional<Packaging> entity = packagingRepository.getById(id);
if(entity.isEmpty()) throw new RuntimeException("Packaging does not exists " + id);
// check integrity
Check.equals(dto.getHu().getId(), entity.get().getHuId());
Check.equals(dto.getHu().getId(), entity.get().getHuId());
Check.equals(dto.getId(), id);
packagingDimensionRepository.update(packagingTransformerService.convertFromPackagingDimensionDTO(dto.getHu()));
packagingDimensionRepository.update(packagingTransformerService.convertFromPackagingDimensionDTO(dto.getShu()));
packagingRepository.update(packagingTransformerService.convertFromPackagingPostDTO(dto));
}
public Integer deletePackaging(Integer id) {
return packagingRepository.deleteById(id).orElseThrow(() -> new RuntimeException("Packaging does not exists " + id));
return packagingRepository.setDeprecatedById(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));
}
@Transactional
public Integer createPackaging(PackagingPostDTO dto) {
public Packaging getPackaging(Integer id) {
return packagingRepository.getById(id).orElseThrow(() -> new RuntimeException("Packaging does not exists " + id));
Optional<Integer> huId = packagingDimensionRepository.insert(packagingTransformerService.convertFromPackagingDimensionDTO(dto.getHu()));
Optional<Integer> shuId = packagingDimensionRepository.insert(packagingTransformerService.convertFromPackagingDimensionDTO(dto.getShu()));
Packaging entity = packagingTransformerService.convertFromPackagingPostDTO(dto);
entity.setHuId(huId.orElseThrow());
entity.setShuId(shuId.orElseThrow());
return packagingRepository.insert(entity).orElseThrow(() -> new RuntimeException("Unable to create Packaging " + entity));
}
}

View file

@ -0,0 +1,46 @@
package de.avatic.lcc.service.transformer;
import de.avatic.lcc.dto.countries.get.CountryGetDTO;
import de.avatic.lcc.dto.countries.get.CountryPropertyGetDTO;
import de.avatic.lcc.model.country.Country;
import de.avatic.lcc.model.properties.CountryProperty;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class CountryTransformerService {
public Optional<CountryGetDTO> convertToCountryGetDTO(Optional<Country> country, List<CountryProperty> properties) {
if (country.isEmpty()) return Optional.empty();
CountryGetDTO dto = new CountryGetDTO();
Country entity = country.get();
dto.setIsoCode(entity.getIsoCode().getCode());
dto.setRegionCode(entity.getRegionCode().getCode());
dto.setName(entity.getIsoCode().getFullName());
dto.setId(entity.getId());
dto.setProperties(properties.stream().map(p -> {
CountryPropertyGetDTO dtoEntry = new CountryPropertyGetDTO();
dtoEntry.setCurrentValue(p.getActiveValue());
dtoEntry.setDraftValue(p.getDraftValue());
dtoEntry.setRequired(p.getType().getRequired());
dtoEntry.setId(p.getType().getId());
dtoEntry.setName(p.getType().getName());
dtoEntry.setExternalMappingId(p.getType().getExternalMappingId());
dtoEntry.setDataType(p.getType().getDataType().name());
return dtoEntry;
}).toList());
return Optional.of(dto);
}
}

View file

@ -0,0 +1,10 @@
package de.avatic.lcc.service.transformer;
import org.springframework.stereotype.Service;
@Service
public class DimensionTransformerService {
}

View file

@ -0,0 +1,141 @@
package de.avatic.lcc.service.transformer;
import de.avatic.lcc.dto.generic.NodeTypeDTO;
import de.avatic.lcc.dto.material.get.*;
import de.avatic.lcc.dto.material.post.MaterialPostDTO;
import de.avatic.lcc.dto.packaging.get.PackagingCountryGetDTO;
import de.avatic.lcc.dto.packaging.get.PackagingDimensionGetDTO;
import de.avatic.lcc.model.country.Country;
import de.avatic.lcc.model.materials.Material;
import de.avatic.lcc.model.nodes.Node;
import de.avatic.lcc.model.packaging.Packaging;
import de.avatic.lcc.model.packaging.PackagingDimension;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Optional;
@Service
public class MaterialTransformerService {
public Material convertFromMaterialPostDTO(MaterialPostDTO dto) {
Material entity = new Material();
entity.setNormalizedPartNumber(normalizePartNumber(dto.getPartNumber()));
entity.setPartNumber(dto.getPartNumber());
entity.setName(dto.getName());
entity.setDeprecated(false);
entity.setId(dto.getId());
entity.setHsCode(dto.getHsCode());
return entity;
}
private String normalizePartNumber(String partNumber) {
if (partNumber.length() > 12) throw new IllegalArgumentException("Part number must be less than 12 characters");
return "000000000000".concat(partNumber).substring(partNumber.length());
}
public Optional<MaterialGetDTO> convertToMaterialGetDTO(Optional<Material> material) {
if (material.isEmpty()) return Optional.empty();
Material entity = material.get();
MaterialGetDTO dtoEntry = new MaterialGetDTO();
dtoEntry.setId(entity.getId());
dtoEntry.setPartNumber(entity.getPartNumber());
dtoEntry.setName(entity.getName());
dtoEntry.setHsCode(entity.getHsCode());
return Optional.of(dtoEntry);
}
public MaterialListGetDTO convertToMaterialListGetDTO(Material entity) {
MaterialListGetDTO dtoEntry = new MaterialListGetDTO();
dtoEntry.setId(entity.getId());
dtoEntry.setPartNumber(entity.getPartNumber());
dtoEntry.setName(entity.getName());
dtoEntry.setHsCode(entity.getHsCode());
return dtoEntry;
}
public MaterialPackagingGetDTO convertToMaterialPackagingGetDTO(Packaging entity, Optional<Node> supplier, Optional<Country> country, Optional<PackagingDimension> hu, Optional<PackagingDimension> shu) {
MaterialPackagingGetDTO dto = new MaterialPackagingGetDTO();
dto.setId(entity.getId());
dto.setDeprecated(entity.getDeprecated());
dto.setHu(convertToMaterialDimensionGetDTO(hu).orElseThrow());
dto.setShu(convertToMaterialDimensionGetDTO(shu).orElseThrow());
dto.setSupplier(convertToMaterialSupplierGetDTO(supplier, country).orElseThrow());
return dto;
}
private Optional<MaterialSupplierGetDTO> convertToMaterialSupplierGetDTO(Optional<Node> entity, Optional<Country> country) {
if(entity.isEmpty()) return Optional.empty();
Node data = entity.get();
MaterialSupplierGetDTO dto = new MaterialSupplierGetDTO();
dto.setId(data.getId());
dto.setAddress(data.getAddress());
dto.setName(data.getName());
dto.setDeprecated(data.getDeprecated());
dto.setTypes(toNodeTypeArrayList(data));
dto.setCountry(convertToMaterialCountryGetDTO(country).orElseThrow());
return Optional.of(dto);
}
private Optional<MaterialCountryGetDTO> convertToMaterialCountryGetDTO(Optional<Country> country) {
if (country.isEmpty()) return Optional.empty();
Country data = country.get();
MaterialCountryGetDTO dto = new MaterialCountryGetDTO();
dto.setId(data.getId());
dto.setRegionCode(data.getRegionCode().name());
dto.setIsoCode(data.getIsoCode().name());
return Optional.of(dto);
}
private ArrayList<NodeTypeDTO> toNodeTypeArrayList(Node entity) {
ArrayList<NodeTypeDTO> types = new ArrayList<>();
if (entity.getSink()) types.add(NodeTypeDTO.SINK);
if (entity.getSource()) types.add(NodeTypeDTO.SOURCE);
if (entity.getIntermediate()) types.add(NodeTypeDTO.INTERMEDIATE);
return types;
}
private Optional<MaterialDimensionGetDTO> convertToMaterialDimensionGetDTO(Optional<PackagingDimension> data) {
if (data.isEmpty()) return Optional.empty();
PackagingDimension dimension = data.get();
MaterialDimensionGetDTO dto = new MaterialDimensionGetDTO();
dto.setId(dimension.getId());
dto.setType(dimension.getType());
dto.setLength(dimension.getDimensionUnit().convertFromMM(dimension.getLength()).doubleValue());
dto.setWidth(dimension.getDimensionUnit().convertFromMM(dimension.getWidth()).doubleValue());
dto.setHeight(dimension.getDimensionUnit().convertFromMM(dimension.getHeight()).doubleValue());
dto.setDimensionUnit(dimension.getDimensionUnit());
dto.setWeight(dimension.getWeightUnit().convertFromG(dimension.getWeight()).doubleValue());
dto.setWeightUnit(dimension.getWeightUnit());
dto.setContentUnitCount(dimension.getContentUnitCount());
dto.setDeprecated(dimension.getDeprecated());
return Optional.of(dto);
}
}

View file

@ -0,0 +1,16 @@
package de.avatic.lcc.service.transformer;
import org.springframework.stereotype.Service;
@Service
public class NodeTransformerService {
private final CountryTransformerService countryTransformerService;
public NodeTransformerService(CountryTransformerService countryTransformerService) {
this.countryTransformerService = countryTransformerService;
}
}

View file

@ -0,0 +1,142 @@
package de.avatic.lcc.service.transformer;
import de.avatic.lcc.dto.generic.NodeTypeDTO;
import de.avatic.lcc.dto.packaging.get.*;
import de.avatic.lcc.dto.packaging.post.PackagingPostDTO;
import de.avatic.lcc.model.country.Country;
import de.avatic.lcc.model.materials.Material;
import de.avatic.lcc.model.nodes.Node;
import de.avatic.lcc.model.packaging.Packaging;
import de.avatic.lcc.model.packaging.PackagingDimension;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Optional;
@Service
public class PackagingTransformerService {
public Optional<PackagingDimensionGetDTO> convertToPackagingDimensionDTO(Optional<PackagingDimension> data) {
if (data.isEmpty()) return Optional.empty();
PackagingDimension dimension = data.get();
PackagingDimensionGetDTO dto = new PackagingDimensionGetDTO();
dto.setId(dimension.getId());
dto.setType(dimension.getType());
dto.setLength(dimension.getDimensionUnit().convertFromMM(dimension.getLength()).doubleValue());
dto.setWidth(dimension.getDimensionUnit().convertFromMM(dimension.getWidth()).doubleValue());
dto.setHeight(dimension.getDimensionUnit().convertFromMM(dimension.getHeight()).doubleValue());
dto.setDimensionUnit(dimension.getDimensionUnit());
dto.setWeight(dimension.getWeightUnit().convertFromG(dimension.getWeight()).doubleValue());
dto.setWeightUnit(dimension.getWeightUnit());
dto.setContentUnitCount(dimension.getContentUnitCount());
dto.setDeprecated(dimension.getDeprecated());
return Optional.of(dto);
}
public Optional<PackagingCountryGetDTO> convertToPackagingCountryDTO(Optional<Country> country) {
if (country.isEmpty()) return Optional.empty();
Country data = country.get();
PackagingCountryGetDTO dto = new PackagingCountryGetDTO();
dto.setId(data.getId());
dto.setRegionCode(data.getRegionCode().name());
dto.setIsoCode(data.getIsoCode().name());
return Optional.of(dto);
}
public Optional<PackagingSupplierGetDTO> convertToPackagingSupplierDTO(Optional<Node> node, Optional<Country> country) {
if (node.isEmpty() || country.isEmpty()) {
return Optional.empty();
}
Node data = node.get();
PackagingSupplierGetDTO dto = new PackagingSupplierGetDTO();
ArrayList<NodeTypeDTO> types = new ArrayList<>();
if (data.getSink()) types.add(NodeTypeDTO.SINK);
if (data.getSource()) types.add(NodeTypeDTO.SOURCE);
if (data.getIntermediate()) types.add(NodeTypeDTO.INTERMEDIATE);
dto.setId(data.getId());
dto.setName(data.getName());
dto.setAddress(data.getAddress());
dto.setCountry(convertToPackagingCountryDTO(country).orElseThrow());
dto.setTypes(types);
dto.setDeprecated(data.getDeprecated());
return Optional.of(dto);
}
public Optional<PackagingMaterialGetDTO> convertToPackagingMaterialDTO(Optional<Material> material) {
if(material.isEmpty()) return Optional.empty();
Material data = material.get();
var dto = new PackagingMaterialGetDTO();
dto.setName(data.getName());
dto.setHsCode(data.getHsCode());
dto.setPartNumber(data.getPartNumber());
dto.setId(data.getId());
return Optional.of(dto);
}
public Optional<PackagingGetDTO> convertToPackagingGetDTO(Optional<Packaging> packaging, Optional<Material> material, Optional<Node> supplier, Optional<Country> country, Optional<PackagingDimension> hu, Optional<PackagingDimension> shu) {
if(packaging.isEmpty()) return Optional.empty();
Packaging data = packaging.get();
var dto = new PackagingGetDTO();
dto.setId(data.getId());
dto.setMaterial(convertToPackagingMaterialDTO(material).orElseThrow());
dto.setSupplier(convertToPackagingSupplierDTO(supplier, country).orElseThrow());
dto.setHu(convertToPackagingDimensionDTO(hu).orElseThrow());
dto.setShu(convertToPackagingDimensionDTO(shu).orElseThrow());
dto.setDeprecated(data.getDeprecated());
return Optional.of(dto);
}
public Packaging convertFromPackagingPostDTO(PackagingPostDTO dto) {
var entity = new Packaging();
entity.setId(dto.getId());
entity.setDeprecated(dto.getDeprecated());
entity.setSupplierId(dto.getSupplierId());
entity.setMaterialId(dto.getMaterialId());
entity.setHuId(dto.getHu().getId());
entity.setShuId(dto.getShu().getId());
return entity;
}
public PackagingDimension convertFromPackagingDimensionDTO(PackagingDimensionGetDTO dto) {
var entity = new PackagingDimension();
entity.setId(dto.getId());
entity.setType(dto.getType());
entity.setLength(dto.getDimensionUnit().convertToMM(dto.getLength()).intValue());
entity.setWidth(dto.getDimensionUnit().convertToMM(dto.getWidth()).intValue());
entity.setHeight(dto.getDimensionUnit().convertToMM(dto.getHeight()).intValue());
entity.setDimensionUnit(dto.getDimensionUnit());
entity.setWeight(dto.getWeightUnit().convertToG(dto.getWeight()).intValue());
entity.setWeightUnit(dto.getWeightUnit());
entity.setContentUnitCount(dto.getContentUnitCount());
entity.setDeprecated(dto.getDeprecated());
return entity;
}
}

View file

@ -0,0 +1,21 @@
package de.avatic.lcc.util;
public class Check {
public static <O1,O2> void equals(O1 o1, O2 o2) {
if(o1 == null && o2 == null) {
return;
}
if(o1 == null || o2 == null) {
throw new InvalidArgumentException();
}
if(!o1.equals(o2)) {
throw new InvalidArgumentException();
}
}
}