Merge branch 'main' of git.avatic.de:avatic/lcc_tool
# Conflicts: # src/main/resources/master_data/01-properties.sql
This commit is contained in:
commit
3f5e3cb115
30 changed files with 653 additions and 133 deletions
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
<div class="caption-column">
|
||||
<div class="caption-column-id">{{ property.name }}: </div>
|
||||
<div class="caption-column-name">Ext. Mapping: {{ property.external_mapping_id }}</div>
|
||||
<div class="caption-column-name">{{ property.description }}</div>
|
||||
<div class="caption-column-name"><basic-badge variant="grey">{{ property.external_mapping_id}}</basic-badge></div>
|
||||
</div>
|
||||
|
||||
<div class="input-column">
|
||||
|
|
@ -43,10 +44,11 @@ import Dropdown from "@/components/UI/Dropdown.vue";
|
|||
import IconButton from "@/components/UI/IconButton.vue";
|
||||
import Tooltip from "@/components/UI/Tooltip.vue";
|
||||
import {parseNumberFromString} from "@/common.js";
|
||||
import BasicBadge from "@/components/UI/BasicBadge.vue";
|
||||
|
||||
export default {
|
||||
name: "Property",
|
||||
components: {Tooltip, IconButton, Dropdown, ToggleSwitch, PhGear, InputField},
|
||||
components: {BasicBadge, Tooltip, IconButton, Dropdown, ToggleSwitch, PhGear, InputField},
|
||||
props: {
|
||||
property: {
|
||||
type: Object,
|
||||
|
|
@ -199,6 +201,7 @@ export default {
|
|||
align-items: center;
|
||||
gap: 2.4rem;
|
||||
height: 8rem;
|
||||
margin: 3.6rem 0 ;
|
||||
}
|
||||
|
||||
.caption-column {
|
||||
|
|
@ -206,6 +209,7 @@ export default {
|
|||
flex-direction: column;
|
||||
font-weight: 300;
|
||||
font-size: 1.4rem;
|
||||
max-width: 60rem;
|
||||
}
|
||||
|
||||
.caption-column-id {
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ export default {
|
|||
created() {
|
||||
this.bulkQuery = this.$route.params.ids;
|
||||
this.ids = new UrlSafeBase64().decodeIds(this.$route.params.ids);
|
||||
this.premiseEditStore.loadPremissesIfNeeded(this.ids, true);
|
||||
this.premiseEditStore.loadPremissesForced(this.ids);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -225,6 +225,9 @@ public class ContainerCalculationResult {
|
|||
* @return The volume utilization ratio of one HU to container volume.
|
||||
*/
|
||||
public double getHuUtilizationByVolume() {
|
||||
if (containerType.getVolume() <= 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
return hu.getVolume(DimensionUnit.M) / containerType.getVolume();
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +248,10 @@ public class ContainerCalculationResult {
|
|||
* @return Weight utilization ratio of one HU to the container's maximum weight.
|
||||
*/
|
||||
public double getHuUtilizationByWeight() {
|
||||
return WeightUnit.KG.convertFromG(hu.getWeight()).doubleValue() / maxContainerWeight;
|
||||
if (maxContainerWeight == null || maxContainerWeight <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return WeightUnit.KG.convertFromG(hu.getWeight()) / maxContainerWeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,11 +61,11 @@ public class NodeController {
|
|||
return ResponseEntity.ok(nodeService.deleteNode(id));
|
||||
}
|
||||
|
||||
// @PutMapping("/{id}")
|
||||
// public ResponseEntity<Integer> updateNode(@PathVariable Integer id, @RequestBody NodeUpdateDTO node) {
|
||||
// Check.equals(id, node.getId());
|
||||
// return ResponseEntity.ok(nodeService.updateNode(node));
|
||||
// }
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<Integer> updateNode(@PathVariable Integer id, @RequestBody NodeUpdateDTO node) {
|
||||
Check.equals(id, node.getId());
|
||||
return ResponseEntity.ok(nodeService.updateNode(node));
|
||||
}
|
||||
|
||||
@GetMapping("/locate")
|
||||
public ResponseEntity<LocateNodeDTO> locateNode(@RequestParam String address) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,15 @@ public class PropertyDTO {
|
|||
@JsonProperty("validation_rule")
|
||||
private String validationRule;
|
||||
|
||||
@JsonProperty("description")
|
||||
private String description;
|
||||
|
||||
@JsonProperty("property_group")
|
||||
private String propertyGroup;
|
||||
|
||||
@JsonProperty("sequence_number")
|
||||
private Integer sequenceNumber;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
|
@ -79,4 +88,28 @@ public class PropertyDTO {
|
|||
public String getValidationRule() {
|
||||
return validationRule;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getPropertyGroup() {
|
||||
return propertyGroup;
|
||||
}
|
||||
|
||||
public void setPropertyGroup(String propertyGroup) {
|
||||
this.propertyGroup = propertyGroup;
|
||||
}
|
||||
|
||||
public Integer getSequenceNumber() {
|
||||
return sequenceNumber;
|
||||
}
|
||||
|
||||
public void setSequenceNumber(Integer sequenceNumber) {
|
||||
this.sequenceNumber = sequenceNumber;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package de.avatic.lcc.excelmodel;
|
|||
import de.avatic.lcc.model.utils.DimensionUnit;
|
||||
import de.avatic.lcc.model.utils.WeightUnit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ExcelPackaging {
|
||||
|
||||
private Integer id;
|
||||
|
|
@ -19,6 +21,8 @@ public class ExcelPackaging {
|
|||
private DimensionUnit shuDimensionUnit;
|
||||
private WeightUnit shuWeightUnit;
|
||||
|
||||
private Integer shuUnitCount;
|
||||
|
||||
private Double huLength;
|
||||
private Double huWidth;
|
||||
private Double huHeight;
|
||||
|
|
@ -27,6 +31,9 @@ public class ExcelPackaging {
|
|||
private DimensionUnit huDimensionUnit;
|
||||
private WeightUnit huWeightUnit;
|
||||
|
||||
private Integer huUnitCount;
|
||||
private Map<String, String> properties;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
@ -146,4 +153,29 @@ public class ExcelPackaging {
|
|||
public void setHuWeightUnit(WeightUnit huWeightUnit) {
|
||||
this.huWeightUnit = huWeightUnit;
|
||||
}
|
||||
|
||||
public Integer getShuUnitCount() {
|
||||
return shuUnitCount;
|
||||
}
|
||||
|
||||
public void setShuUnitCount(Integer shuUnitCount) {
|
||||
this.shuUnitCount = shuUnitCount;
|
||||
}
|
||||
|
||||
public Integer getHuUnitCount() {
|
||||
return huUnitCount;
|
||||
}
|
||||
|
||||
public void setHuUnitCount(Integer huUnitCount) {
|
||||
this.huUnitCount = huUnitCount;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ public enum SystemPropertyMappingId {
|
|||
|
||||
KLT_HANDLING("GR handling KLT [EUR/HU]", "0,71 €"),
|
||||
GLT_HANDLING("GR handling GLT [EUR/HU]", "3,50 €"),
|
||||
BOOKING("GLT/KLT booking & document handling [EUR/GR]", "3,50 €"),
|
||||
BOOKING("GLT booking & document handling [EUR/GR]", "3,50 €"),
|
||||
BOOKING_KLT("KLT booking & document handling [EUR/GR]", "0,35 €"),
|
||||
GLT_RELEASE("GLT release from storage [EUR/GLT release]", "2,23 €"),
|
||||
KLT_RELEASE("KLT release from storage [EUR/KLT release]", "1,12 €"),
|
||||
GLT_DISPATCH("GLT dispatch [EUR/GLT dispatch]", "1,61 €"),
|
||||
|
|
|
|||
|
|
@ -79,6 +79,23 @@ public class MaterialRepository {
|
|||
return jdbcTemplate.query(query, new MaterialMapper(), params.toArray());
|
||||
}
|
||||
|
||||
public Optional<Material> getByPartNumber(String partNumber) {
|
||||
if (partNumber == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String query = "SELECT * FROM material WHERE part_number = ? OR normalized_part_number = ?";
|
||||
|
||||
var material = jdbcTemplate.query(query, new MaterialMapper(), partNumber, partNumber);
|
||||
|
||||
if(material.isEmpty())
|
||||
return Optional.empty();
|
||||
|
||||
return Optional.ofNullable(material.getFirst());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Transactional
|
||||
public Optional<Integer> setDeprecatedById(Integer id) {
|
||||
String query = "UPDATE material SET is_deprecated = TRUE WHERE id = ?";
|
||||
|
|
@ -190,6 +207,8 @@ public class MaterialRepository {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class MaterialMapper implements RowMapper<Material> {
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -65,8 +65,12 @@ public class CountryPropertyRepository {
|
|||
type.external_mapping_id as externalMappingId,
|
||||
type.validation_rule as validationRule,
|
||||
type.is_required as is_required,
|
||||
type.description as description,
|
||||
type.property_group as propertyGroup,
|
||||
type.sequence_number as sequenceNumber,
|
||||
draft.property_value as draftValue,
|
||||
valid.property_value as validValue
|
||||
|
||||
FROM country_property_type AS type
|
||||
LEFT JOIN (
|
||||
SELECT cp.property_value, cp.country_property_type_id
|
||||
|
|
@ -104,6 +108,10 @@ public class CountryPropertyRepository {
|
|||
type.external_mapping_id as externalMappingId,
|
||||
type.validation_rule as validationRule,
|
||||
type.is_required as is_required,
|
||||
type.is_required as is_required,
|
||||
type.description as description,
|
||||
type.property_group as propertyGroup,
|
||||
type.sequence_number as sequenceNumber,
|
||||
MAX(CASE WHEN ps.state = 'DRAFT' THEN cp.property_value END) as draftValue,
|
||||
MAX(CASE WHEN ps.state = 'VALID' THEN cp.property_value END) as validValue
|
||||
FROM country_property_type AS type
|
||||
|
|
@ -121,6 +129,9 @@ public class CountryPropertyRepository {
|
|||
|
||||
String query = """
|
||||
SELECT type.name as name, type.data_type as dataType, type.external_mapping_id as externalMappingId, type.validation_rule as validationRule, type.is_required as is_required,
|
||||
type.description as description,
|
||||
type.property_group as propertyGroup,
|
||||
type.sequence_number as sequenceNumber,
|
||||
property.property_value as draftValue, property.property_value as validValue
|
||||
FROM country_property_type AS type
|
||||
LEFT JOIN country_property AS property ON property.country_property_type_id = type.id
|
||||
|
|
@ -161,6 +172,10 @@ public class CountryPropertyRepository {
|
|||
dto.setRequired(rs.getBoolean("is_required"));
|
||||
dto.setDataType(rs.getString("dataType"));
|
||||
|
||||
dto.setDescription(rs.getString("description"));
|
||||
dto.setPropertyGroup(rs.getString("propertyGroup"));
|
||||
dto.setSequenceNumber(rs.getInt("sequenceNumber"));
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,4 +101,19 @@ public class PackagingPropertiesRepository {
|
|||
|
||||
jdbcTemplate.update(query, value, packagingId, typeId, value);
|
||||
}
|
||||
|
||||
public Integer getTypeIdByMappingId(String mappingId) {
|
||||
String query = "SELECT id FROM packaging_property_type WHERE external_mapping_id = ?";
|
||||
return jdbcTemplate.queryForObject(query, Integer.class, mappingId);
|
||||
}
|
||||
|
||||
public void update(Integer packagingId, String typeId, String value) {
|
||||
|
||||
String query = """
|
||||
INSERT INTO packaging_property (property_value, packaging_id, packaging_property_type_id) VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE property_value = ?""";
|
||||
|
||||
jdbcTemplate.update(query, value, packagingId, typeId, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,13 +92,14 @@ public class PropertyRepository {
|
|||
|
||||
String query = """
|
||||
SELECT type.name as name, type.data_type as dataType, type.external_mapping_id as externalMappingId, type.validation_rule as validationRule,
|
||||
type.description as description, type.property_group as propertyGroup, type.sequence_number as sequenceNumber,
|
||||
MAX(CASE WHEN ps.state = ? THEN sp.property_value END) as draftValue,
|
||||
MAX(CASE WHEN ps.state = ? THEN sp.property_value END) as validValue
|
||||
FROM system_property_type AS type
|
||||
LEFT JOIN system_property AS sp ON sp.system_property_type_id = type.id
|
||||
LEFT JOIN property_set AS ps ON ps.id = sp.property_set_id AND ps.state IN (?, ?)
|
||||
GROUP BY type.id, type.name, type.data_type, type.external_mapping_id, type.validation_rule
|
||||
HAVING draftValue IS NOT NULL OR validValue IS NOT NULL ORDER BY type.name;
|
||||
GROUP BY type.id, type.name, type.data_type, type.external_mapping_id, type.validation_rule, type.description, type.property_group, type.sequence_number
|
||||
HAVING draftValue IS NOT NULL OR validValue IS NOT NULL ORDER BY type.property_group , type.sequence_number;
|
||||
""";
|
||||
|
||||
return jdbcTemplate.query(query, new PropertyMapper(), ValidityPeriodState.DRAFT.name(), ValidityPeriodState.VALID.name(), ValidityPeriodState.DRAFT.name(), ValidityPeriodState.VALID.name());
|
||||
|
|
@ -115,11 +116,12 @@ public class PropertyRepository {
|
|||
|
||||
String query = """
|
||||
SELECT type.name as name, type.data_type as dataType, type.external_mapping_id as externalMappingId, type.validation_rule as validationRule,
|
||||
type.description as description, type.property_group as propertyGroup, type.sequence_number as sequenceNumber,
|
||||
NULL as draftValue, property.property_value as validValue
|
||||
FROM system_property_type AS type
|
||||
LEFT JOIN system_property AS property ON property.system_property_type_id = type.id
|
||||
LEFT JOIN property_set AS propertySet ON propertySet.id = property.property_set_id
|
||||
WHERE propertySet.id = ? AND (propertySet.state = ? OR propertySet.state = ?) ORDER BY type.name;
|
||||
WHERE propertySet.id = ? AND (propertySet.state = ? OR propertySet.state = ?) ORDER BY type.property_group , type.sequence_number;
|
||||
""";
|
||||
|
||||
return jdbcTemplate.query(query, new PropertyMapper(), propertySetId, ValidityPeriodState.EXPIRED.name(), ValidityPeriodState.INVALID.name());
|
||||
|
|
@ -129,6 +131,7 @@ public class PropertyRepository {
|
|||
public Optional<PropertyDTO> getPropertyByMappingId(SystemPropertyMappingId mappingId) {
|
||||
String query = """
|
||||
SELECT type.name as name, type.data_type as dataType, type.external_mapping_id as externalMappingId, type.validation_rule as validationRule,
|
||||
type.description as description, type.property_group as propertyGroup, type.sequence_number as sequenceNumber,
|
||||
property.property_value as draftValue, property.property_value as validValue
|
||||
FROM system_property_type AS type
|
||||
LEFT JOIN system_property AS property ON property.system_property_type_id = type.id
|
||||
|
|
@ -190,6 +193,10 @@ public class PropertyRepository {
|
|||
dto.setRequired(true);
|
||||
dto.setDataType(rs.getString("dataType"));
|
||||
|
||||
dto.setDescription(rs.getString("description"));
|
||||
dto.setPropertyGroup(rs.getString("propertyGroup"));
|
||||
dto.setSequenceNumber(rs.getInt("sequenceNumber"));
|
||||
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,8 +107,7 @@ public class NodeService {
|
|||
* @param includeUserNode if true, includes user-specific nodes in the search results.
|
||||
* @return a list of {@link NodeDTO} objects representing the search results.
|
||||
*/
|
||||
public List<NodeDTO> searchNode(String filter, int limit, NodeType nodeType, boolean includeUserNode) {
|
||||
List<NodeDTO> nodes = new ArrayList<>();
|
||||
public List<NodeDTO> searchNode(String filter, int limit, NodeType nodeType, boolean includeUserNode) { List<NodeDTO> nodes = new ArrayList<>();
|
||||
int userId = 1; //TODO get current user's id
|
||||
|
||||
if( includeUserNode && NodeType.SOURCE.equals(nodeType)) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Service for managing properties and property sets within the application.
|
||||
|
|
@ -117,4 +118,40 @@ public class PropertyService {
|
|||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Optional<T> getProperty(SystemPropertyMappingId mappingId) {
|
||||
var prop = propertyRepository.getPropertyByMappingId(mappingId);
|
||||
|
||||
if (prop.isEmpty())
|
||||
return Optional.empty();
|
||||
|
||||
var property = prop.get();
|
||||
var propValue = property.getCurrentValue();
|
||||
var dataType = property.getDataType();
|
||||
|
||||
if (propValue == null)
|
||||
return Optional.empty();
|
||||
|
||||
try {
|
||||
Object convertedValue = convertStringByDataType(propValue, dataType);
|
||||
return Optional.of((T) convertedValue);
|
||||
} catch (ClassCastException e) {
|
||||
// The caller expected a different type than what the dataType indicates
|
||||
return Optional.empty();
|
||||
} catch (Exception e) {
|
||||
// Parsing error
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private Object convertStringByDataType(String value, String dataType) {
|
||||
return switch (dataType.toUpperCase()) {
|
||||
case "TEXT", "ENUMERATION" -> value;
|
||||
case "CURRENCY", "PERCENTAGE" -> Double.valueOf(value);
|
||||
case "BOOLEAN" -> Boolean.valueOf(value);
|
||||
case "INT" -> Integer.valueOf(value);
|
||||
default -> throw new IllegalArgumentException("Unsupported data type: " + dataType);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import de.avatic.lcc.model.properties.CountryPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.PackagingPropertyMappingId;
|
||||
import de.avatic.lcc.model.properties.PropertyDataType;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.repositories.country.CountryPropertyRepository;
|
||||
import de.avatic.lcc.repositories.packaging.PackagingPropertiesRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.util.exception.badrequest.PropertyValidationException;
|
||||
import de.avatic.lcc.util.exception.base.InternalErrorException;
|
||||
|
|
@ -23,11 +25,13 @@ public class PropertyValidationService {
|
|||
|
||||
private final CountryPropertyRepository countryPropertyRepository;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final PackagingPropertiesRepository packagingPropertiesRepository;
|
||||
|
||||
public PropertyValidationService(ObjectMapper objectMapper, CountryPropertyRepository countryPropertyRepository, PropertyRepository propertyRepository) {
|
||||
public PropertyValidationService(ObjectMapper objectMapper, CountryPropertyRepository countryPropertyRepository, PropertyRepository propertyRepository, PackagingPropertiesRepository packagingPropertiesRepository) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.countryPropertyRepository = countryPropertyRepository;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.packagingPropertiesRepository = packagingPropertiesRepository;
|
||||
}
|
||||
|
||||
public void validateProperty(SystemPropertyMappingId mappingId, String value) {
|
||||
|
|
@ -36,6 +40,13 @@ public class PropertyValidationService {
|
|||
validate(mappingId.name(), PropertyDataType.valueOf(property.orElseThrow().getDataType()), property.orElseThrow().getValidationRule(), value);
|
||||
}
|
||||
|
||||
public void validatePackagingProperty(Integer packagingId, PackagingPropertyMappingId mappingId, String value) {
|
||||
|
||||
var property = packagingPropertiesRepository.getByPackagingIdAndType(packagingId, mappingId.name());
|
||||
validate(mappingId.name(), property.orElseThrow().getType().getDataType(), property.orElseThrow().getType().getValidationRule(), value);
|
||||
|
||||
}
|
||||
|
||||
public void validateCountryProperty(Integer countryId, CountryPropertyMappingId mappingId, String value) {
|
||||
|
||||
var property = countryPropertyRepository.getByMappingIdAndCountryId(mappingId, countryId);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@ import de.avatic.lcc.model.bulk.BulkFileTypes;
|
|||
import de.avatic.lcc.model.bulk.BulkInstruction;
|
||||
import de.avatic.lcc.model.bulk.BulkInstructionType;
|
||||
import de.avatic.lcc.model.bulk.BulkOperation;
|
||||
import de.avatic.lcc.model.nodes.Node;
|
||||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.service.bulk.bulkImport.NodeBulkImportService;
|
||||
import de.avatic.lcc.service.bulk.bulkImport.PackagingBulkImportService;
|
||||
import de.avatic.lcc.service.excelMapper.*;
|
||||
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
|
||||
import de.avatic.lcc.util.exception.internalerror.ExcelValidationError;
|
||||
|
|
@ -17,6 +20,7 @@ import org.springframework.stereotype.Service;
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class BulkImportService {
|
||||
|
|
@ -28,8 +32,10 @@ public class BulkImportService {
|
|||
private final NodeExcelMapper nodeExcelMapper;
|
||||
private final NodeRepository nodeRepository;
|
||||
private final NodeTransformer nodeTransformer;
|
||||
private final NodeBulkImportService nodeBulkImportService;
|
||||
private final PackagingBulkImportService packagingBulkImportService;
|
||||
|
||||
public BulkImportService(MatrixRateExcelMapper matrixRateExcelMapper, ContainerRateExcelMapper containerRateExcelMapper, MaterialExcelMapper materialExcelMapper, PackagingExcelMapper packagingExcelMapper, NodeExcelMapper nodeExcelMapper, NodeRepository nodeRepository, NodeTransformer nodeTransformer) {
|
||||
public BulkImportService(MatrixRateExcelMapper matrixRateExcelMapper, ContainerRateExcelMapper containerRateExcelMapper, MaterialExcelMapper materialExcelMapper, PackagingExcelMapper packagingExcelMapper, NodeExcelMapper nodeExcelMapper, NodeRepository nodeRepository, NodeTransformer nodeTransformer, NodeBulkImportService nodeBulkImportService, PackagingBulkImportService packagingBulkImportService) {
|
||||
this.matrixRateExcelMapper = matrixRateExcelMapper;
|
||||
this.containerRateExcelMapper = containerRateExcelMapper;
|
||||
this.materialExcelMapper = materialExcelMapper;
|
||||
|
|
@ -37,6 +43,8 @@ public class BulkImportService {
|
|||
this.nodeExcelMapper = nodeExcelMapper;
|
||||
this.nodeRepository = nodeRepository;
|
||||
this.nodeTransformer = nodeTransformer;
|
||||
this.nodeBulkImportService = nodeBulkImportService;
|
||||
this.packagingBulkImportService = packagingBulkImportService;
|
||||
}
|
||||
|
||||
public void processOperation(BulkOperation op) throws IOException {
|
||||
|
|
@ -63,10 +71,11 @@ public class BulkImportService {
|
|||
break;
|
||||
case PACKAGING:
|
||||
var packaging = packagingExcelMapper.extractSheet(sheet);
|
||||
packaging.forEach(packagingBulkImportService::processPackagingInstructions);
|
||||
break;
|
||||
case NODE:
|
||||
var nodeInstructions = nodeExcelMapper.extractSheet(sheet);
|
||||
nodeInstructions.forEach(this::processNodeInstructions);
|
||||
nodeInstructions.forEach(nodeBulkImportService::processNodeInstructions);
|
||||
break;
|
||||
default:
|
||||
|
||||
|
|
@ -75,31 +84,5 @@ public class BulkImportService {
|
|||
|
||||
}
|
||||
|
||||
private void processNodeInstructions(BulkInstruction<ExcelNode> instr) {
|
||||
|
||||
BulkInstructionType instrType = instr.getType();
|
||||
ExcelNode excelNode = instr.getEntity();
|
||||
|
||||
|
||||
if (instrType == BulkInstructionType.UPDATE) {
|
||||
updateNode(excelNode);
|
||||
} else if (instrType == BulkInstructionType.DELETE) {
|
||||
deleteNode(excelNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteNode(ExcelNode excelNode) {
|
||||
nodeRepository.setDeprecatedById(excelNode.getId());
|
||||
}
|
||||
|
||||
private void updateNode(ExcelNode excelNode) {
|
||||
var node = nodeRepository.getByExternalMappingId(excelNode.getExternalMappingId());
|
||||
|
||||
if(node.isEmpty()) {
|
||||
nodeRepository.insert(nodeTransformer.toNodeEntity(excelNode));
|
||||
} else {
|
||||
nodeRepository.update(nodeTransformer.toNodeEntity(excelNode));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
package de.avatic.lcc.service.bulk.bulkImport;
|
||||
|
||||
import de.avatic.lcc.excelmodel.ExcelNode;
|
||||
import de.avatic.lcc.model.bulk.BulkInstruction;
|
||||
import de.avatic.lcc.model.bulk.BulkInstructionType;
|
||||
import de.avatic.lcc.model.nodes.Node;
|
||||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.service.transformer.generic.NodeTransformer;
|
||||
import de.avatic.lcc.util.exception.internalerror.ExcelValidationError;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class NodeBulkImportService {
|
||||
|
||||
|
||||
private final NodeRepository nodeRepository;
|
||||
private final NodeTransformer nodeTransformer;
|
||||
|
||||
public NodeBulkImportService(NodeRepository nodeRepository, NodeTransformer nodeTransformer) {
|
||||
this.nodeRepository = nodeRepository;
|
||||
this.nodeTransformer = nodeTransformer;
|
||||
}
|
||||
|
||||
public void processNodeInstructions(BulkInstruction<ExcelNode> instr) {
|
||||
|
||||
BulkInstructionType instrType = instr.getType();
|
||||
ExcelNode excelNode = instr.getEntity();
|
||||
|
||||
|
||||
if (instrType == BulkInstructionType.UPDATE) {
|
||||
updateNode(excelNode);
|
||||
} else if (instrType == BulkInstructionType.DELETE) {
|
||||
deleteNode(excelNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteNode(ExcelNode excelNode) {
|
||||
var node = nodeRepository.getByExternalMappingId(excelNode.getExternalMappingId());
|
||||
|
||||
if (node.isEmpty()) {
|
||||
throw new ExcelValidationError("Node with external mapping id " + excelNode.getExternalMappingId() + " not found");
|
||||
} else {
|
||||
nodeRepository.setDeprecatedById(node.get().getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNode(ExcelNode excelNode) {
|
||||
var node = nodeRepository.getByExternalMappingId(excelNode.getExternalMappingId());
|
||||
|
||||
if (node.isEmpty()) {
|
||||
nodeRepository.insert(nodeTransformer.toNodeEntity(excelNode));
|
||||
} else {
|
||||
var convertedNode = nodeTransformer.toNodeEntity(excelNode);
|
||||
convertedNode.setId(node.get().getId());
|
||||
if (!compare(convertedNode, node.get())) {
|
||||
nodeRepository.update(convertedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean compare(Node updateNode, Node currentNode) {
|
||||
|
||||
return updateNode.getName().equals(currentNode.getName()) &&
|
||||
updateNode.getGeoLat().compareTo(currentNode.getGeoLat()) == 0 &&
|
||||
updateNode.getGeoLng().compareTo(currentNode.getGeoLng()) == 0 &&
|
||||
updateNode.getExternalMappingId().equals(currentNode.getExternalMappingId()) &&
|
||||
updateNode.getCountryId().equals(currentNode.getCountryId()) &&
|
||||
updateNode.getIntermediate().equals(currentNode.getIntermediate()) &&
|
||||
updateNode.getDestination().equals(currentNode.getDestination()) &&
|
||||
updateNode.getSource().equals(currentNode.getSource()) &&
|
||||
updateNode.getAddress().equals(currentNode.getAddress()) &&
|
||||
updateNode.getDeprecated().equals(currentNode.getDeprecated()) &&
|
||||
updateNode.getId().equals(currentNode.getId()) &&
|
||||
updateNode.getPredecessorRequired().equals(currentNode.getPredecessorRequired()) &&
|
||||
compare(updateNode.getNodePredecessors(), currentNode.getNodePredecessors()) &&
|
||||
compare(updateNode.getOutboundCountries(), currentNode.getOutboundCountries());
|
||||
|
||||
}
|
||||
|
||||
private boolean compare(Collection<Integer> outbound1, Collection<Integer> outbound2) {
|
||||
if (outbound1 == null && outbound2 == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (outbound1 == null || outbound2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outbound1.size() != outbound2.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var set1 = new HashSet<>(outbound1);
|
||||
var set2 = new HashSet<>(outbound2);
|
||||
return set1.equals(set2);
|
||||
}
|
||||
|
||||
private boolean compare(List<Map<Integer, Integer>> chain1, List<Map<Integer, Integer>> chain2) {
|
||||
|
||||
if (chain1 == null && chain2 == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (chain1 == null || chain2 == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (chain1.size() != chain2.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Map<Integer, Integer>> set1 = new HashSet<>(chain1);
|
||||
Set<Map<Integer, Integer>> set2 = new HashSet<>(chain2);
|
||||
|
||||
return set1.equals(set2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package de.avatic.lcc.service.bulk.bulkImport;
|
||||
|
||||
import de.avatic.lcc.excelmodel.ExcelPackaging;
|
||||
import de.avatic.lcc.model.bulk.BulkInstruction;
|
||||
import de.avatic.lcc.model.bulk.BulkInstructionType;
|
||||
import de.avatic.lcc.model.packaging.Packaging;
|
||||
import de.avatic.lcc.model.packaging.PackagingType;
|
||||
import de.avatic.lcc.model.properties.PackagingPropertyMappingId;
|
||||
import de.avatic.lcc.repositories.MaterialRepository;
|
||||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.repositories.packaging.PackagingDimensionRepository;
|
||||
import de.avatic.lcc.repositories.packaging.PackagingPropertiesRepository;
|
||||
import de.avatic.lcc.repositories.packaging.PackagingRepository;
|
||||
import de.avatic.lcc.service.access.PropertyValidationService;
|
||||
import de.avatic.lcc.service.transformer.generic.DimensionTransformer;
|
||||
import de.avatic.lcc.util.exception.internalerror.ExcelValidationError;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PackagingBulkImportService {
|
||||
|
||||
|
||||
private final PackagingRepository packagingRepository;
|
||||
private final MaterialRepository materialRepository;
|
||||
private final NodeRepository nodeRepository;
|
||||
private final PackagingDimensionRepository packagingDimensionRepository;
|
||||
|
||||
private final DimensionTransformer dimensionTransformer;
|
||||
private final PackagingPropertiesRepository packagingPropertiesRepository;
|
||||
private final PropertyValidationService propertyValidationService;
|
||||
|
||||
public PackagingBulkImportService(PackagingRepository packagingRepository, MaterialRepository materialRepository, NodeRepository nodeRepository, PackagingDimensionRepository packagingDimensionRepository, DimensionTransformer dimensionTransformer, PackagingPropertiesRepository packagingPropertiesRepository, PropertyValidationService propertyValidationService) {
|
||||
this.packagingRepository = packagingRepository;
|
||||
this.materialRepository = materialRepository;
|
||||
this.nodeRepository = nodeRepository;
|
||||
this.packagingDimensionRepository = packagingDimensionRepository;
|
||||
this.dimensionTransformer = dimensionTransformer;
|
||||
this.packagingPropertiesRepository = packagingPropertiesRepository;
|
||||
this.propertyValidationService = propertyValidationService;
|
||||
}
|
||||
|
||||
public void processPackagingInstructions(BulkInstruction<ExcelPackaging> instr) {
|
||||
BulkInstructionType instrType = instr.getType();
|
||||
ExcelPackaging excelPackaging = instr.getEntity();
|
||||
|
||||
|
||||
if (instrType == BulkInstructionType.UPDATE) {
|
||||
updatePackaging(excelPackaging);
|
||||
} else if (instrType == BulkInstructionType.DELETE) {
|
||||
deletePackaging(excelPackaging);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void deletePackaging(ExcelPackaging excelPackaging) {
|
||||
var material = materialRepository.getByPartNumber(excelPackaging.getPartNumber());
|
||||
var supplier = nodeRepository.getByExternalMappingId(excelPackaging.getSupplierMappingId());
|
||||
|
||||
if (material.isEmpty() || supplier.isEmpty()) {
|
||||
throw new ExcelValidationError("Packaging references non existing supplier \"" + excelPackaging.getSupplierMappingId() + "\" and/or material \"" + excelPackaging.getPartNumber() + "\"");
|
||||
} else {
|
||||
packagingRepository.getByMaterialIdAndSupplierId(material.get().getId(), supplier.get().getId()).ifPresent(packaging -> packagingRepository.setDeprecatedById(packaging.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updatePackaging(ExcelPackaging excelPackaging) {
|
||||
var material = materialRepository.getByPartNumber(excelPackaging.getPartNumber());
|
||||
var supplier = nodeRepository.getByExternalMappingId(excelPackaging.getSupplierMappingId());
|
||||
|
||||
if (material.isEmpty() || supplier.isEmpty()) {
|
||||
throw new ExcelValidationError("Packaging references non existing supplier \"" + excelPackaging.getSupplierMappingId() + "\" and/or material \"" + excelPackaging.getPartNumber() + "\"");
|
||||
} else {
|
||||
var excelHu = dimensionTransformer.toDimensionEntity(excelPackaging, PackagingType.HU);
|
||||
var excelShu = dimensionTransformer.toDimensionEntity(excelPackaging, PackagingType.SHU);
|
||||
|
||||
var packaging = packagingRepository.getByMaterialIdAndSupplierId(material.get().getId(), supplier.get().getId());
|
||||
|
||||
if (packaging.isEmpty()) {
|
||||
var huId = packagingDimensionRepository.insert(excelHu).orElseThrow();
|
||||
var shuId = packagingDimensionRepository.insert(excelShu).orElseThrow();
|
||||
|
||||
var convertedPackaging = new Packaging();
|
||||
convertedPackaging.setMaterialId(material.get().getId());
|
||||
convertedPackaging.setSupplierId(supplier.get().getId());
|
||||
convertedPackaging.setDeprecated(false);
|
||||
convertedPackaging.setHuId(huId);
|
||||
convertedPackaging.setShuId(shuId);
|
||||
|
||||
packagingRepository.insert(convertedPackaging);
|
||||
|
||||
} else {
|
||||
var hu = packaging.flatMap(o -> packagingDimensionRepository.getById(o.getHuId()));
|
||||
var shu = packaging.flatMap(o -> packagingDimensionRepository.getById(o.getShuId()));
|
||||
|
||||
excelHu.setId(hu.isEmpty() ? packagingDimensionRepository.insert(excelHu).orElseThrow() : hu.get().getId());
|
||||
excelShu.setId(shu.isEmpty() ? packagingDimensionRepository.insert(excelShu).orElseThrow() : shu.get().getId());
|
||||
|
||||
var convertedPackaging = new Packaging();
|
||||
convertedPackaging.setMaterialId(material.get().getId());
|
||||
convertedPackaging.setSupplierId(supplier.get().getId());
|
||||
convertedPackaging.setDeprecated(false);
|
||||
convertedPackaging.setHuId(excelHu.getId());
|
||||
convertedPackaging.setShuId(excelShu.getId());
|
||||
convertedPackaging.setId(packaging.get().getId());
|
||||
|
||||
if (hu.isPresent())
|
||||
packagingDimensionRepository.update(excelHu);
|
||||
|
||||
if (shu.isPresent())
|
||||
packagingDimensionRepository.update(excelShu);
|
||||
|
||||
for (var mappingId : excelPackaging.getProperties().keySet()) {
|
||||
var id = packagingPropertiesRepository.getTypeIdByMappingId(mappingId);
|
||||
propertyValidationService.validatePackagingProperty(id, PackagingPropertyMappingId.valueOf(mappingId), excelPackaging.getProperties().get(mappingId));
|
||||
packagingPropertiesRepository.update(convertedPackaging.getId(), id, excelPackaging.getProperties().get(mappingId));
|
||||
}
|
||||
|
||||
packagingRepository.update(convertedPackaging);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -193,6 +193,22 @@ public class ConstraintGenerator {
|
|||
|
||||
}
|
||||
|
||||
public void validateIntegerCell(Row row, int columnIdx) {
|
||||
CellType cellType = row.getCell(columnIdx).getCellType();
|
||||
|
||||
if (cellType == CellType.NUMERIC) {
|
||||
|
||||
double value = row.getCell(columnIdx).getNumericCellValue();
|
||||
|
||||
if(value % 1 == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ExcelValidationError("Unable to validate row " + (row.getRowNum() + 1) + " column " + toExcelLetter(columnIdx) + ": Expected integer value");
|
||||
|
||||
}
|
||||
|
||||
public void validateStringCell(Row row, int columnIdx) {
|
||||
CellType cellType = row.getCell(columnIdx).getCellType();
|
||||
|
||||
|
|
@ -202,7 +218,7 @@ public class ConstraintGenerator {
|
|||
return;
|
||||
}
|
||||
|
||||
throw new ExcelValidationError("Unable to validate row " + (row.getRowNum() + 1) + " column " + toExcelLetter(columnIdx) + ": Expected numeric value");
|
||||
throw new ExcelValidationError("Unable to validate row " + (row.getRowNum() + 1) + " column " + toExcelLetter(columnIdx) + ": Expected string value");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,9 +99,14 @@ public class PremiseSearchStringAnalyzerService {
|
|||
while (matcher.find()) {
|
||||
// Get the match from group 1 (inside the lookahead)
|
||||
String partNumber = matcher.group(1);
|
||||
partNumbers.add(partNumber);
|
||||
partNumbers.add(normalizePartNumber(partNumber));
|
||||
}
|
||||
|
||||
return partNumbers;
|
||||
}
|
||||
|
||||
private static 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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,19 +48,6 @@ public class CustomCostCalculationService {
|
|||
}
|
||||
}
|
||||
|
||||
public CustomResult doD2dCalculation(Premise premise, Destination destination, List<SectionInfo> sections) {
|
||||
|
||||
var destUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, destination.getCountryId()).orElseThrow();
|
||||
var sourceUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, premise.getCountryId()).orElseThrow();
|
||||
|
||||
if (!CustomUnionType.EU.name().equals(destUnion.getCurrentValue()) || !CustomUnionType.NONE.name().equals(sourceUnion.getCurrentValue()))
|
||||
return CustomResult.EMPTY;
|
||||
|
||||
double huAnnualAmount = BigDecimal.valueOf(destination.getAnnualAmount()).divide(BigDecimal.valueOf(sections.getFirst().containerResult().getHuUnitCount()),2, RoundingMode.HALF_UP).doubleValue();
|
||||
|
||||
return getCustomCalculationResult(premise, destination, getContainerShare(premise, sections.getFirst().containerResult()), huAnnualAmount, sections.getFirst().result().getAnnualCost(), sections.getFirst().result().getAnnualChanceCost(), sections.getFirst().result().getAnnualRiskCost());
|
||||
}
|
||||
|
||||
public CustomResult doCalculation(Premise premise, Destination destination, List<SectionInfo> sections) {
|
||||
|
||||
var destUnion = countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.UNION, destination.getCountryId()).orElseThrow();
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class HandlingCostCalculationService {
|
|||
BigDecimal disposal = destinationDisposal != null ? destinationDisposal : BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.DISPOSAL).orElseThrow().getCurrentValue()));
|
||||
|
||||
BigDecimal wageFactor = BigDecimal.valueOf(Double.parseDouble(countryPropertyRepository.getByMappingIdAndCountryId(CountryPropertyMappingId.WAGE, destination.getCountryId()).orElseThrow().getCurrentValue()));
|
||||
BigDecimal booking = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING).orElseThrow().getCurrentValue()));
|
||||
BigDecimal booking = BigDecimal.valueOf(Double.parseDouble(propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.BOOKING_KLT).orElseThrow().getCurrentValue()));
|
||||
|
||||
return new HandlingResult(LoadCarrierType.SLC,
|
||||
getRepackingCost(hu, loadCarrierType, addRepackingCosts, destinationRepacking).multiply(huAnnualAmount),
|
||||
|
|
|
|||
|
|
@ -20,11 +20,9 @@ import de.avatic.lcc.service.bulk.helper.HeaderGenerator;
|
|||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class PackagingExcelMapper {
|
||||
|
|
@ -132,19 +130,32 @@ public class PackagingExcelMapper {
|
|||
|
||||
}
|
||||
|
||||
public List<ExcelPackaging> extractSheet(Sheet sheet) {
|
||||
public List<BulkInstruction<ExcelPackaging>> extractSheet(Sheet sheet) {
|
||||
headerGenerator.validateHeader(sheet, PackagingHeader.class);
|
||||
Map<Integer, String> propertyMappingIds = getPropertyHeaders(sheet.getRow(0));
|
||||
|
||||
var packaging = new ArrayList<ExcelPackaging>();
|
||||
var packaging = new ArrayList<BulkInstruction<ExcelPackaging>>();
|
||||
sheet.forEach(row -> {
|
||||
if(row.getRowNum() == 0) return;
|
||||
packaging.add(mapToEntity(row));
|
||||
packaging.add(mapToEntity(row, propertyMappingIds));
|
||||
});
|
||||
return packaging;
|
||||
}
|
||||
|
||||
private Map<Integer, String> getPropertyHeaders(Row row) {
|
||||
var propertyMappingIds = packagingPropertiesRepository.listTypes().stream().map(PropertyType::getExternalMappingId).toList();
|
||||
|
||||
private ExcelPackaging mapToEntity(Row row) {
|
||||
var headers = new HashMap<Integer, String>();
|
||||
for (int i = 0; i < row.getLastCellNum(); i++) {
|
||||
if (propertyMappingIds.contains(row.getCell(i).getStringCellValue())) {
|
||||
headers.put(i, row.getCell(i).getStringCellValue());
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
private BulkInstruction<ExcelPackaging> mapToEntity(Row row, Map<Integer, String> propertyMappingIds) {
|
||||
ExcelPackaging entity = new ExcelPackaging();
|
||||
|
||||
validateConstraints(row);
|
||||
|
|
@ -168,7 +179,12 @@ public class PackagingExcelMapper {
|
|||
entity.setShuDimensionUnit(DimensionUnit.valueOf(row.getCell(PackagingHeader.SHU_DIMENSION_UNIT.ordinal()).getStringCellValue()));
|
||||
entity.setShuWeightUnit(WeightUnit.valueOf(row.getCell(PackagingHeader.SHU_WEIGHT_UNIT.ordinal()).getStringCellValue()));
|
||||
|
||||
return entity;
|
||||
entity.setHuUnitCount(Double.valueOf(row.getCell(PackagingHeader.HU_UNIT_COUNT.ordinal()).getNumericCellValue()).intValue());
|
||||
entity.setShuUnitCount(Double.valueOf(row.getCell(PackagingHeader.SHU_UNIT_COUNT.ordinal()).getNumericCellValue()).intValue());
|
||||
|
||||
entity.setProperties(propertyMappingIds.keySet().stream().collect(Collectors.toMap(propertyMappingIds::get, idx -> row.getCell(idx).getStringCellValue())));
|
||||
|
||||
return new BulkInstruction<>(entity, BulkInstructionType.valueOf(row.getCell(PackagingHeader.OPERATION.ordinal()).getStringCellValue()));
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -186,6 +202,9 @@ public class PackagingExcelMapper {
|
|||
constraintGenerator.validateNumericCell(row, PackagingHeader.SHU_LENGTH.ordinal());
|
||||
constraintGenerator.validateNumericCell(row, PackagingHeader.SHU_WEIGHT.ordinal());
|
||||
|
||||
constraintGenerator.validateIntegerCell(row, PackagingHeader.HU_UNIT_COUNT.ordinal());
|
||||
constraintGenerator.validateIntegerCell(row, PackagingHeader.SHU_UNIT_COUNT.ordinal());
|
||||
|
||||
constraintGenerator.validateLengthConstraint(row, PackagingHeader.PART_NUMBER.ordinal(), 0, 12);
|
||||
constraintGenerator.validateEnumConstraint(row, PackagingHeader.SHU_DIMENSION_UNIT.ordinal(), DimensionUnit.class);
|
||||
constraintGenerator.validateEnumConstraint(row, PackagingHeader.SHU_WEIGHT_UNIT.ordinal(), WeightUnit.class);
|
||||
|
|
|
|||
|
|
@ -1,34 +1,49 @@
|
|||
package de.avatic.lcc.service.precalculation;
|
||||
|
||||
import de.avatic.lcc.dto.generic.ContainerType;
|
||||
import de.avatic.lcc.model.nodes.Node;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
import de.avatic.lcc.model.premises.route.Destination;
|
||||
import de.avatic.lcc.model.premises.route.Route;
|
||||
import de.avatic.lcc.model.properties.SystemPropertyMappingId;
|
||||
import de.avatic.lcc.model.utils.WeightUnit;
|
||||
import de.avatic.lcc.repositories.NodeRepository;
|
||||
import de.avatic.lcc.repositories.premise.DestinationRepository;
|
||||
import de.avatic.lcc.repositories.premise.PremiseRepository;
|
||||
import de.avatic.lcc.repositories.premise.RouteRepository;
|
||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||
import de.avatic.lcc.service.CustomApiService;
|
||||
import de.avatic.lcc.service.access.PropertyService;
|
||||
import de.avatic.lcc.service.transformer.generic.DimensionTransformer;
|
||||
import de.avatic.lcc.util.exception.internalerror.PremiseValidationError;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class PreCalculationCheckService {
|
||||
|
||||
private static final double DIMENSION_TOLERANCE = 0.02;
|
||||
|
||||
private final PremiseRepository premiseRepository;
|
||||
private final CustomApiService customApiService;
|
||||
private final DestinationRepository destinationRepository;
|
||||
private final RouteRepository routeRepository;
|
||||
private final NodeRepository nodeRepository;
|
||||
private final DimensionTransformer dimensionTransformer;
|
||||
private final PropertyRepository propertyRepository;
|
||||
private final PropertyService propertyService;
|
||||
|
||||
public PreCalculationCheckService(PremiseRepository premiseRepository, CustomApiService customApiService, DestinationRepository destinationRepository, RouteRepository routeRepository, NodeRepository nodeRepository) {
|
||||
public PreCalculationCheckService(PremiseRepository premiseRepository, CustomApiService customApiService, DestinationRepository destinationRepository, RouteRepository routeRepository, NodeRepository nodeRepository, DimensionTransformer dimensionTransformer, PropertyRepository propertyRepository, PropertyService propertyService) {
|
||||
this.premiseRepository = premiseRepository;
|
||||
this.customApiService = customApiService;
|
||||
this.destinationRepository = destinationRepository;
|
||||
this.routeRepository = routeRepository;
|
||||
this.nodeRepository = nodeRepository;
|
||||
this.dimensionTransformer = dimensionTransformer;
|
||||
this.propertyRepository = propertyRepository;
|
||||
this.propertyService = propertyService;
|
||||
}
|
||||
|
||||
public void doPrecheck(Integer premiseId) {
|
||||
|
|
@ -59,7 +74,6 @@ public class PreCalculationCheckService {
|
|||
var routes = routeRepository.getByDestinationId(destination.getId());
|
||||
|
||||
|
||||
|
||||
if (routes.isEmpty() && destination.getD2d() == false)
|
||||
throw new PremiseValidationError("No route found for destination " + node.getName() + ". Cannot use standard routing.");
|
||||
|
||||
|
|
@ -183,6 +197,24 @@ public class PreCalculationCheckService {
|
|||
throw new PremiseValidationError("Packaging dimension unit is not set");
|
||||
}
|
||||
|
||||
var hu = dimensionTransformer.toDimensionEntity(premise).withTolerance(DIMENSION_TOLERANCE);
|
||||
|
||||
Optional<Integer> teuLoad = propertyService.getProperty(SystemPropertyMappingId.TEU_LOAD);
|
||||
Optional<Integer> feuLoad = propertyService.getProperty(SystemPropertyMappingId.TEU_LOAD);
|
||||
|
||||
if (teuLoad.isEmpty() || feuLoad.isEmpty())
|
||||
throw new PremiseValidationError("There is a system property misconfiguration. Please contact administrator");
|
||||
|
||||
if (WeightUnit.KG.convertFromG(hu.getWeight()) > teuLoad.get() && hu.getWeight() > feuLoad.get())
|
||||
throw new PremiseValidationError("The handling unit is too heavy. Configured maximum is " + Math.max(teuLoad.get(), feuLoad.get()) + " kg. ");
|
||||
|
||||
var teuFitsXY = (hu.getLength() < ContainerType.TEU.getLength() && hu.getWidth() < ContainerType.TEU.getWidth());
|
||||
var teuFitsYX = (hu.getWidth() < ContainerType.TEU.getLength() && hu.getLength() < ContainerType.TEU.getWidth());
|
||||
|
||||
if (!teuFitsYX && !teuFitsXY) {
|
||||
throw new PremiseValidationError("The handling unit is too big. Has to fit into twenty food equivalent (minus " + DIMENSION_TOLERANCE + " tolerance) container.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void materialCheck(Premise premise) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package de.avatic.lcc.service.transformer.generic;
|
||||
|
||||
import de.avatic.lcc.dto.generic.DimensionDTO;
|
||||
import de.avatic.lcc.excelmodel.ExcelPackaging;
|
||||
import de.avatic.lcc.model.packaging.PackagingDimension;
|
||||
import de.avatic.lcc.model.packaging.PackagingType;
|
||||
import de.avatic.lcc.model.premises.Premise;
|
||||
|
|
@ -108,4 +109,46 @@ public class DimensionTransformer {
|
|||
|
||||
return dto;
|
||||
}
|
||||
|
||||
public PackagingDimension toDimensionEntity(ExcelPackaging packaging, PackagingType type) {
|
||||
PackagingDimension dimension = new PackagingDimension();
|
||||
|
||||
if (type == PackagingType.HU) {
|
||||
WeightUnit weightUnit = packaging.getHuWeightUnit();
|
||||
DimensionUnit unit = packaging.getHuDimensionUnit();
|
||||
|
||||
dimension.setLength(unit.convertToMM(packaging.getHuLength()));
|
||||
dimension.setHeight(unit.convertToMM(packaging.getHuHeight()));
|
||||
dimension.setWidth(unit.convertToMM(packaging.getHuWidth()));
|
||||
dimension.setDimensionUnit(unit);
|
||||
|
||||
dimension.setWeight(weightUnit.convertToG(packaging.getHuWeight()));
|
||||
dimension.setWeightUnit(weightUnit);
|
||||
|
||||
dimension.setContentUnitCount(packaging.getHuUnitCount());
|
||||
dimension.setType(PackagingType.HU);
|
||||
|
||||
dimension.setDeprecated(false);
|
||||
|
||||
} else if (type == PackagingType.SHU) {
|
||||
WeightUnit weightUnit = packaging.getShuWeightUnit();
|
||||
DimensionUnit unit = packaging.getShuDimensionUnit();
|
||||
|
||||
dimension.setLength(unit.convertToMM(packaging.getShuLength()));
|
||||
dimension.setHeight(unit.convertToMM(packaging.getShuHeight()));
|
||||
dimension.setWidth(unit.convertToMM(packaging.getShuWidth()));
|
||||
dimension.setDimensionUnit(unit);
|
||||
|
||||
dimension.setWeight(weightUnit.convertToG(packaging.getShuWeight()));
|
||||
dimension.setWeightUnit(weightUnit);
|
||||
|
||||
dimension.setContentUnitCount(packaging.getShuUnitCount());
|
||||
dimension.setType(PackagingType.SHU);
|
||||
|
||||
dimension.setDeprecated(false);
|
||||
}
|
||||
|
||||
|
||||
return dimension;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ public class NodeTransformer {
|
|||
}
|
||||
|
||||
entity.setId(excelNode.getId());
|
||||
entity.setExternalMappingId(excelNode.getExternalMappingId());
|
||||
|
||||
entity.setName(excelNode.getName());
|
||||
entity.setAddress(excelNode.getAddress());
|
||||
entity.setCountryId(countryId.get().getId());
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ public class MaterialDetailPackagingPropertyTransformer {
|
|||
dto.setExternalMappingId(property.getType().getExternalMappingId());
|
||||
dto.setValidationRule(property.getType().getValidationRule());
|
||||
|
||||
|
||||
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,51 +5,51 @@
|
|||
-- Description -> name
|
||||
-- ===================================================
|
||||
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Reference route: Port of origin', 'START_REF', 'TEXT', '{}','Reference route used to demonstrate sea freight fluctuation, port in country of origin','Reference route','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Reference route: Port of destination', 'END_REF', 'TEXT', '{}','Reference route used to demonstrate sea freight fluctuation, port in country of destination','Reference route','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'All-time-high container rate (40 ft.) [EUR]', 'RISK_REF', 'CURRENCY', '{"GT":0}','Highest container rate to be used to demnastrate sea freight fluctuation, cost for 40 Ft. (FEU) general purpose container','Reference route','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'All-time-low container rate (40 ft.) [EUR]', 'CHANCE_REF', 'CURRENCY', '{"GT":0}','Lowest container rate to be used to demnastrate sea freight fluctuation, cost for 40 Ft. (FEU) general purpose container','Reference route','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Payment terms [days]', 'PAYMENT_TERMS', 'INT', '{}','Payment target [days] agreed with suppliers','General','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Annual working days', 'WORKDAYS', 'INT', '{"GT": 0, "LT": 366}','Annual working days (production)','General','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Interest rate inventory [%]', 'INTEREST_RATE', 'PERCENTAGE', '{"GTE": 0}','Calculatory interest rate for inventories and payment targets','General','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'FCA fee [%]', 'FCA_FEE', 'PERCENTAGE', '{"GTE": 0}','FCA fee to be added on EXW prices (MEK_A)','General','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Default customs rate [%]', 'TARIFF_RATE', 'PERCENTAGE', '{"GTE":0}','Customs rate to be applied, if no exact value is available','General','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Customs clearance fee per import & HS code [EUR]', 'CUSTOM_FEE', 'CURRENCY', '{"GTE":0}','Average customs clearance fee charged for the import of one HS code per import (mixed container)','General','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Standard reporting format', 'REPORTING', 'ENUMERATION', '{"ENUM":["MEK_B","MEK_C"]}','Defines standard format for reports (MEK_B = excl. Risks, MEK_C = incl. risks)','General','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( '40 ft.', 'FEU', 'BOOLEAN', '{}','To be activated, if calculation shall be possible with this container size. Container rates to be maintained.','Sea and road transport','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( '20 ft.', 'TEU', 'BOOLEAN', '{}','To be activated, if calculation shall be possible with this container size. Container rates to be maintained.','Sea and road transport','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( '40 ft. HC', 'FEU_HQ', 'BOOLEAN', '{}','To be activated, if calculation shall be possible with this container size. Container rates to be maintained.','Sea and road transport','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Container utilization in mixed containers [%]', 'CONTAINER_UTIL', 'PERCENTAGE', '{"GTE":0,"LTE":1}','Defines, to which degree the volume of a mixed container shall be utilized (loss due to inefficient stacking and different packaging sizes).','Sea and road transport','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Truck utilization road transport EMEA [%]', 'TRUCK_UTIL', 'PERCENTAGE', '{"GTE":0,"LTE":1}','Defines, to which degree the volume of a truck shall be utilized (loss due to inefficient stacking and different packaging sizes).','Sea and road transport','8');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Max validity period of container freight rates [days]', 'VALID_DAYS', 'INT', '{"GT": 0}','Defines the maximum period of time, after which container freight rates cannot be used for calculations anymore.','General','8');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Metropolition region size (diameter) [km]', 'RADIUS_REGION', 'INT', '{"GT": 0}','Defines the average distance a supplier may have from a defined source (e.g. center of metropolitan area), for which a container rate is maintained.','General','9');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Min delivery frequency / year for containter transports', 'FREQ_MIN', 'INT', '{"GT": 0, "LT": 366}','Relevant for low runners; defines into how many deliveries a HU shall be split, if HU content >= yearly demand (e.g. 4 = 1/4 of yearly demand is allocated to a shipment)','General','10');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Max delivery frequency / year for containter transport', 'FREQ_MAX', 'INT', '{"GT": 0, "LT": 366}','Relevant for high runners; defines the maximum shipping frequency for sea shipments (e.g. 52 = weekly, 104 = 2x/week, 12 = monthly etc.)','General','11');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Max load 20 ft. container [kg]', 'TEU_LOAD', 'INT', '{"GT": 0}','Defines the weight limit of a TEU container.','Sea and road transport','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Max load 40 ft. container [kg]', 'FEU_LOAD', 'INT', '{"GT": 0}','Defines the weight limit of a FEU container. Can be also limited by local law (e.g. road transport weight in CN limited to 21 tons).','Sea and road transport','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Max load truck [kg]', 'TRUCK_LOAD', 'INT', '{"GT": 0}','Defines the weight limit of a truck (use standard type, usually 40-ton truck)','Sea and road transport','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Pre-carriage [EUR/kg]', 'AIR_PRECARRIAGE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for pre-carriage to airport in country of origin','Air transport','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Pre-carriage handling [EUR]', 'AIR_HANDLING', 'CURRENCY', '{"GTE": 0}','For air transports only: one time costs for handling of air shipments (documents)','Air transport','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Main carriage [EUR/kg]', 'AIR_MAINCARRIAGE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for flight. (use as reference route the flight route with the highest traffic, e.g. CN-DE)','Air transport','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Hand over fee [EUR]', 'AIR_HANDOVER_FEE', 'CURRENCY', '{"GTE": 0}','For air transports only: one time cost for handover of air shipment ','Air transport','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Customs clearance fee [EUR]', 'AIR_CUSTOM_FEE', 'CURRENCY', '{"GTE": 0}','For air transports only: one time cost for customs clearance of air shipment ','Air transport','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'On-carriage [EUR/kg]', 'AIR_ONCARRIAGE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for on-carriage from airport to destination','Air transport','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Terminal handling fee [EUR/kg]', 'AIR_TERMINAL_FEE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for handling of shipment in airport terminal','Air transport','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'GR handling KLT [EUR/HU] (DE)', 'KLT_HANDLING', 'CURRENCY', '{"GTE": 0}','Cost per KLT for the handling in the Goods Receipt area of a warehouse or plant; reference country: Germany','Warehouse','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'GR handling GLT [EUR/HU] (DE)', 'GLT_HANDLING', 'CURRENCY', '{"GTE": 0}','Cost per GLT for the handling in the Goods Receipt area of a warehouse or plant; reference country: Germany','Warehouse','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'GLT booking & document handling [EUR/GR] (DE)', 'BOOKING', 'CURRENCY', '{"GTE": 0}','One time document handling fee for 1 GLT; reference country: Germany','Warehouse','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'GLT release from storage [EUR/GLT release] (DE)', 'GLT_RELEASE', 'CURRENCY', '{"GTE": 0}','Cost to release one GLT from the storage; reference country: Germany','Warehouse','12');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'KLT release from storage [EUR/KLT release] (DE)', 'KLT_RELEASE', 'CURRENCY', '{"GTE": 0}','Cost to release one KLT from the storage; reference country: Germany','Warehouse','11');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'GLT dispatch [EUR/GLT dispatch] (DE)', 'GLT_DISPATCH', 'CURRENCY', '{"GTE": 0}','Cost to disptach one GLT; reference country: Germany','Warehouse','14');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'KLT dispacth [EUR/KLT dispatch] (DE)', 'KLT_DISPATCH', 'CURRENCY', '{"GTE": 0}','Cost to disptach one KLT; reference country: Germany','Warehouse','13');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Repacking KLT, HU <15kg [EUR/HU] (DE)', 'KLT_REPACK_S', 'CURRENCY', '{"GTE": 0}','Cost to repack one KLT (<15 kg) from one-way to returnable empty; reference country: Germany','Warehouse','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Repacking KLT, HU >=15kg [EUR/HU] (DE)', 'KLT_REPACK_M', 'CURRENCY', '{"GTE": 0}','Cost to repack one KLT (>=15 kg) from one-way to returnable empty with crane handling; reference country: Germany','Warehouse','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Repacking GLT, HU <15kg [EUR/HU] (DE)', 'GLT_REPACK_S', 'CURRENCY', '{"GTE": 0}','Cost to repack one GLT (<15 kg) from oneway to returnable empty; reference country: Germany','Warehouse','8');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Repacking GLT, HU 15 - 2000kg [EUR/HU] (DE)', 'GLT_REPACK_M', 'CURRENCY', '{"GTE": 0}','Cost to repack one GLT (>=15 - 2000 kg) from one-way to returnable empty with crane handling; reference country: Germany','Warehouse','9');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Repacking GLT, HU >2000kg [EUR/HU] (DE)', 'GLT_REPACK_L', 'INT', '{"GTE": 0}','Cost to repack one GLT (> 2000 kg, e.g. counterweight) from one-way to returnable empty with crane handling; reference country: Germany','Warehouse','10');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'GLT disposal [EUR/GLT] (DE)', 'DISPOSAL', 'INT', '{"GTE": 0}','Cost to dispose one wooden pallet (value valid for all countries)','Warehouse','15');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'Space costs per cbm per night [EUR/cbm] (DE)', 'SPACE_COST', 'CURRENCY', '{"GTE": 0}','Cost per month for a standard storage bin (1,20 x 0,80 x 1,00 m)','Warehouse','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sort_id) VALUES ( 'KLT booking & document handling [EUR/GR] (DE)', 'BOOKING_KLT', 'CURRENCY', '{"GTE": 0}','One time document handling fee for 1 KLT; reference country: Germany','Warehouse','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Reference route: Port of origin', 'START_REF', 'TEXT', '{}','Reference route used to demonstrate sea freight fluctuation, port in country of origin','Reference route','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Reference route: Port of destination', 'END_REF', 'TEXT', '{}','Reference route used to demonstrate sea freight fluctuation, port in country of destination','Reference route','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'All-time-high container rate (40 ft.) [EUR]', 'RISK_REF', 'CURRENCY', '{"GT":0}','Highest container rate to be used to demnastrate sea freight fluctuation, cost for 40 Ft. (FEU) general purpose container','Reference route','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'All-time-low container rate (40 ft.) [EUR]', 'CHANCE_REF', 'CURRENCY', '{"GT":0}','Lowest container rate to be used to demnastrate sea freight fluctuation, cost for 40 Ft. (FEU) general purpose container','Reference route','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Payment terms [days]', 'PAYMENT_TERMS', 'INT', '{}','Payment target [days] agreed with suppliers','General','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Annual working days', 'WORKDAYS', 'INT', '{"GT": 0, "LT": 366}','Annual working days (production)','General','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Interest rate inventory [%]', 'INTEREST_RATE', 'PERCENTAGE', '{"GTE": 0}','Calculatory interest rate for inventories and payment targets','General','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'FCA fee [%]', 'FCA_FEE', 'PERCENTAGE', '{"GTE": 0}','FCA fee to be added on EXW prices (MEK_A)','General','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Default customs rate [%]', 'TARIFF_RATE', 'PERCENTAGE', '{"GTE":0}','Customs rate to be applied, if no exact value is available','General','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Customs clearance fee per import & HS code [EUR]', 'CUSTOM_FEE', 'CURRENCY', '{"GTE":0}','Average customs clearance fee charged for the import of one HS code per import (mixed container)','General','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Standard reporting format', 'REPORTING', 'ENUMERATION', '{"ENUM":["MEK_B","MEK_C"]}','Defines standard format for reports (MEK_B = excl. Risks, MEK_C = incl. risks)','General','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( '40 ft.', 'FEU', 'BOOLEAN', '{}','To be activated, if calculation shall be possible with this container size. Container rates to be maintained.','Sea and road transport','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( '20 ft.', 'TEU', 'BOOLEAN', '{}','To be activated, if calculation shall be possible with this container size. Container rates to be maintained.','Sea and road transport','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( '40 ft. HC', 'FEU_HQ', 'BOOLEAN', '{}','To be activated, if calculation shall be possible with this container size. Container rates to be maintained.','Sea and road transport','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Container utilization in mixed containers [%]', 'CONTAINER_UTIL', 'PERCENTAGE', '{"GTE":0,"LTE":1}','Defines, to which degree the volume of a mixed container shall be utilized (loss due to inefficient stacking and different packaging sizes).','Sea and road transport','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Truck utilization road transport EMEA [%]', 'TRUCK_UTIL', 'PERCENTAGE', '{"GTE":0,"LTE":1}','Defines, to which degree the volume of a truck shall be utilized (loss due to inefficient stacking and different packaging sizes).','Sea and road transport','8');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Max validity period of container freight rates [days]', 'VALID_DAYS', 'INT', '{"GT": 0}','Defines the maximum period of time, after which container freight rates cannot be used for calculations anymore.','General','8');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Metropolition region size (diameter) [km]', 'RADIUS_REGION', 'INT', '{"GT": 0}','Defines the average distance a supplier may have from a defined source (e.g. center of metropolitan area), for which a container rate is maintained.','General','9');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Min delivery frequency / year for containter transports', 'FREQ_MIN', 'INT', '{"GT": 0, "LT": 366}','Relevant for low runners; defines into how many deliveries a HU shall be split, if HU content >= yearly demand (e.g. 4 = 1/4 of yearly demand is allocated to a shipment)','General','10');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Max delivery frequency / year for containter transport', 'FREQ_MAX', 'INT', '{"GT": 0, "LT": 366}','Relevant for high runners; defines the maximum shipping frequency for sea shipments (e.g. 52 = weekly, 104 = 2x/week, 12 = monthly etc.)','General','11');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Max load 20 ft. container [kg]', 'TEU_LOAD', 'INT', '{"GT": 0}','Defines the weight limit of a TEU container.','Sea and road transport','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Max load 40 ft. container [kg]', 'FEU_LOAD', 'INT', '{"GT": 0}','Defines the weight limit of a FEU container. Can be also limited by local law (e.g. road transport weight in CN limited to 21 tons).','Sea and road transport','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Max load truck [kg]', 'TRUCK_LOAD', 'INT', '{"GT": 0}','Defines the weight limit of a truck (use standard type, usually 40-ton truck)','Sea and road transport','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Pre-carriage [EUR/kg]', 'AIR_PRECARRIAGE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for pre-carriage to airport in country of origin','Air transport','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Pre-carriage handling [EUR]', 'AIR_HANDLING', 'CURRENCY', '{"GTE": 0}','For air transports only: one time costs for handling of air shipments (documents)','Air transport','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Main carriage [EUR/kg]', 'AIR_MAINCARRIAGE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for flight. (use as reference route the flight route with the highest traffic, e.g. CN-DE)','Air transport','3');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Hand over fee [EUR]', 'AIR_HANDOVER_FEE', 'CURRENCY', '{"GTE": 0}','For air transports only: one time cost for handover of air shipment ','Air transport','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Customs clearance fee [EUR]', 'AIR_CUSTOM_FEE', 'CURRENCY', '{"GTE": 0}','For air transports only: one time cost for customs clearance of air shipment ','Air transport','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'On-carriage [EUR/kg]', 'AIR_ONCARRIAGE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for on-carriage from airport to destination','Air transport','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Terminal handling fee [EUR/kg]', 'AIR_TERMINAL_FEE', 'CURRENCY', '{"GTE": 0}','For air transports only: cost per kg for handling of shipment in airport terminal','Air transport','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'GR handling KLT [EUR/HU] (DE)', 'KLT_HANDLING', 'CURRENCY', '{"GTE": 0}','Cost per KLT for the handling in the Goods Receipt area of a warehouse or plant; reference country: Germany','Warehouse','4');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'GR handling GLT [EUR/HU] (DE)', 'GLT_HANDLING', 'CURRENCY', '{"GTE": 0}','Cost per GLT for the handling in the Goods Receipt area of a warehouse or plant; reference country: Germany','Warehouse','5');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'GLT booking & document handling [EUR/GR] (DE)', 'BOOKING', 'CURRENCY', '{"GTE": 0}','One time document handling fee for 1 GLT; reference country: Germany','Warehouse','2');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'GLT release from storage [EUR/GLT release] (DE)', 'GLT_RELEASE', 'CURRENCY', '{"GTE": 0}','Cost to release one GLT from the storage; reference country: Germany','Warehouse','12');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'KLT release from storage [EUR/KLT release] (DE)', 'KLT_RELEASE', 'CURRENCY', '{"GTE": 0}','Cost to release one KLT from the storage; reference country: Germany','Warehouse','11');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'GLT dispatch [EUR/GLT dispatch] (DE)', 'GLT_DISPATCH', 'CURRENCY', '{"GTE": 0}','Cost to disptach one GLT; reference country: Germany','Warehouse','14');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'KLT dispacth [EUR/KLT dispatch] (DE)', 'KLT_DISPATCH', 'CURRENCY', '{"GTE": 0}','Cost to disptach one KLT; reference country: Germany','Warehouse','13');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Repacking KLT, HU <15kg [EUR/HU] (DE)', 'KLT_REPACK_S', 'CURRENCY', '{"GTE": 0}','Cost to repack one KLT (<15 kg) from one-way to returnable empty; reference country: Germany','Warehouse','6');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Repacking KLT, HU >=15kg [EUR/HU] (DE)', 'KLT_REPACK_M', 'CURRENCY', '{"GTE": 0}','Cost to repack one KLT (>=15 kg) from one-way to returnable empty with crane handling; reference country: Germany','Warehouse','7');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Repacking GLT, HU <15kg [EUR/HU] (DE)', 'GLT_REPACK_S', 'CURRENCY', '{"GTE": 0}','Cost to repack one GLT (<15 kg) from oneway to returnable empty; reference country: Germany','Warehouse','8');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Repacking GLT, HU 15 - 2000kg [EUR/HU] (DE)', 'GLT_REPACK_M', 'CURRENCY', '{"GTE": 0}','Cost to repack one GLT (>=15 - 2000 kg) from one-way to returnable empty with crane handling; reference country: Germany','Warehouse','9');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Repacking GLT, HU >2000kg [EUR/HU] (DE)', 'GLT_REPACK_L', 'INT', '{"GTE": 0}','Cost to repack one GLT (> 2000 kg, e.g. counterweight) from one-way to returnable empty with crane handling; reference country: Germany','Warehouse','10');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'GLT disposal [EUR/GLT] (DE)', 'DISPOSAL', 'INT', '{"GTE": 0}','Cost to dispose one wooden pallet (value valid for all countries)','Warehouse','15');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'Space costs per cbm per night [EUR/cbm] (DE)', 'SPACE_COST', 'CURRENCY', '{"GTE": 0}','Cost per month for a standard storage bin (1,20 x 0,80 x 1,00 m)','Warehouse','1');
|
||||
INSERT INTO system_property_type ( name, external_mapping_id, data_type, validation_rule, description, property_group, sequence_number) VALUES ( 'KLT booking & document handling [EUR/GR] (DE)', 'BOOKING_KLT', 'CURRENCY', '{"GTE": 0}','One time document handling fee for 1 KLT; reference country: Germany','Warehouse','3');
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ WHERE NOT EXISTS (
|
|||
-- =============================================================================
|
||||
|
||||
INSERT INTO `country_property_type`
|
||||
(`name`, `external_mapping_id`, `data_type`, `validation_rule`, `is_required`)
|
||||
(`name`, `external_mapping_id`, `data_type`, `validation_rule`, `is_required`, `description`, `property_group`, `sequence_number`)
|
||||
VALUES
|
||||
('Customs Union', 'UNION', 'ENUMERATION', '{ "ENUM" : ["EU", "NONE"]}', FALSE),
|
||||
('Safety Stock [working days]', 'SAFETY_STOCK', 'INT', '{"GTE": 0}', FALSE),
|
||||
('Air Freight Share [%]', 'AIR_SHARE', 'PERCENTAGE', '{"GTE": 0}', FALSE),
|
||||
('Wage Factor [%]', 'WAGE', 'PERCENTAGE', '{"GT": 0}', FALSE);
|
||||
('Customs Union', 'UNION', 'ENUMERATION', '{ "ENUM" : ["EU", "NONE"]}', FALSE, 'Custom union description', 'General', 1),
|
||||
('Safety Stock [working days]', 'SAFETY_STOCK', 'INT', '{"GTE": 0}', FALSE, 'Safety stock description', 'General', 2),
|
||||
('Air Freight Share [%]', 'AIR_SHARE', 'PERCENTAGE', '{"GTE": 0}', FALSE, 'Air freight description', 'General', 3),
|
||||
('Wage Factor [%]', 'WAGE', 'PERCENTAGE', '{"GT": 0}', FALSE, 'Wage factor description', 'General', 4);
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. INSERT COUNTRIES
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
INSERT INTO packaging_property_type (name, external_mapping_id, data_type, validation_rule, is_required)
|
||||
VALUES
|
||||
('Stackable', 'STACKABLE', 'BOOLEAN', NULL, FALSE),
|
||||
('Rust Prevention', 'RUST_PREVENTION', 'BOOLEAN', NULL, FALSE)
|
||||
('Rust Prevention', 'RUST_PREVENTION', 'BOOLEAN', NULL, FALSE),
|
||||
('Mixable', 'MIXABLE', 'BOOLEAN', NULL, FALSE)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
data_type = VALUES(data_type);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ CREATE TABLE IF NOT EXISTS `system_property_type`
|
|||
`external_mapping_id` VARCHAR(16),
|
||||
`description` VARCHAR(255) NOT NULL,
|
||||
`property_group` VARCHAR(32) NOT NULL,
|
||||
`sort_id` INT,
|
||||
`sequence_number` INT NOT NULL,
|
||||
`data_type` VARCHAR(16) NOT NULL,
|
||||
`validation_rule` VARCHAR(64),
|
||||
UNIQUE KEY `idx_external_mapping` (`external_mapping_id`),
|
||||
|
|
@ -52,6 +52,9 @@ CREATE TABLE IF NOT EXISTS `country`
|
|||
`iso_code` CHAR(2) NOT NULL COMMENT 'ISO 3166-1 alpha-2 country code',
|
||||
`region_code` CHAR(5) NOT NULL COMMENT 'Geographic region code (EMEA/LATAM/APAC/NAM)',
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` VARCHAR(255) NOT NULL,
|
||||
`property_group` VARCHAR(32) NOT NULL,
|
||||
`sequence_number` INT NOT NULL,
|
||||
`is_deprecated` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_country_iso_code` (`iso_code`),
|
||||
|
|
@ -308,6 +311,9 @@ CREATE TABLE IF NOT EXISTS packaging_property_type
|
|||
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
external_mapping_id VARCHAR(16) NOT NULL,
|
||||
`description` VARCHAR(255) NOT NULL,
|
||||
`property_group` VARCHAR(32) NOT NULL,
|
||||
`sequence_number` INT NOT NULL,
|
||||
`data_type` VARCHAR(16),
|
||||
`validation_rule` VARCHAR(64),
|
||||
`is_required` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue