From d9b27bc987757c84918cae0d6f421243c0b38566 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 6 Nov 2025 18:13:08 +0100 Subject: [PATCH] Integrated `EUTaxationApiWrapperService` for enhanced tariff rate calculations: - **Backend**: Introduced `getTariffRateImmediate` method for immediate tariff rate retrieval, replacing `CustomApiService` in relevant services. Updated constructor dependencies across services. - **Frontend**: Added tariff measure sorting by code for improved data presentation in customs store. --- src/frontend/src/store/customs.js | 2 + .../lcc/service/api/CustomApiService.java | 2 +- .../api/EUTaxationApiWrapperService.java | 51 +++++++++++++++++++ .../calculation/ChangeMaterialService.java | 7 ++- .../calculation/ChangeSupplierService.java | 7 ++- .../calculation/PremiseCreationService.java | 7 ++- 6 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/frontend/src/store/customs.js b/src/frontend/src/store/customs.js index fb40398..ef47527 100644 --- a/src/frontend/src/store/customs.js +++ b/src/frontend/src/store/customs.js @@ -39,6 +39,8 @@ export const useCustomsStore = defineStore('customs', { }) this.tariffInfo = resp.data; + this.tariffInfo.forEach(info => info.measures.sort((m1, m2) => { return parseInt(m1.code) - parseInt(m2.code); })); + this.loadingTariff = false; return this.tariffInfo; }, diff --git a/src/main/java/de/avatic/lcc/service/api/CustomApiService.java b/src/main/java/de/avatic/lcc/service/api/CustomApiService.java index f23116a..448e2c2 100644 --- a/src/main/java/de/avatic/lcc/service/api/CustomApiService.java +++ b/src/main/java/de/avatic/lcc/service/api/CustomApiService.java @@ -32,7 +32,7 @@ public class CustomApiService { private final String taricApiKey; private final PropertyRepository propertyRepository; - public CustomApiService(@Value("${taric.api.key}") String taricApiKey, @Value("${taric.api.url}") String taricApiUrl, CountryRepository countryRepository, RestTemplate restTemplate, ObjectMapper objectMapper, PropertyRepository propertyRepository) { + public CustomApiService(@Value("${taric.api.key:}") String taricApiKey, @Value("${taric.api.url:}") String taricApiUrl, CountryRepository countryRepository, RestTemplate restTemplate, ObjectMapper objectMapper, PropertyRepository propertyRepository) { this.taricApiKey = taricApiKey; this.taricApiUrl = taricApiUrl; this.countryRepository = countryRepository; diff --git a/src/main/java/de/avatic/lcc/service/api/EUTaxationApiWrapperService.java b/src/main/java/de/avatic/lcc/service/api/EUTaxationApiWrapperService.java index 0da7d63..9caa955 100644 --- a/src/main/java/de/avatic/lcc/service/api/EUTaxationApiWrapperService.java +++ b/src/main/java/de/avatic/lcc/service/api/EUTaxationApiWrapperService.java @@ -34,6 +34,57 @@ public class EUTaxationApiWrapperService { return futures.stream().map(CompletableFuture::join).toList(); } + + public CustomDTO getTariffRateImmediate(String hsCode, Integer countryId) { + var country = countryRepository.getById(countryId); + String iso = country.orElseThrow().getIsoCode().name(); + + List customMeasures = new ArrayList<>(); + + try { + var measForWsResponse = eUTaxationApiService.getGoodsMeasures(hsCode, iso.toUpperCase(), "I"); + + GoodsMeasuresForWsResponse.Measures.Measure selectedMeasure = null; + Double selectedDuty = null; + int rank = Integer.MAX_VALUE; + + var measures = filterToNewestMeasuresPerType(measForWsResponse.getReturn().getResult().getMeasures().getMeasure()); + + + for (var measure : measures) { + var measureType = MeasureType.fromMeasureCode(measure.getMeasureType().getMeasureType()); + boolean maybeRelevant = measureType.map(MeasureType::containsRelevantDuty).orElse(false); + + if (maybeRelevant) { + var duty = extractDuty(measure); + + if (rank > measureType.get().ordinal() && duty.isPresent()) { + rank = measureType.get().ordinal(); + selectedDuty = duty.get(); + selectedMeasure = measure; + } + } + + customMeasures.add(new CustomMeasureDTO( + measure.getMeasureType().getMeasureType(), + measure.getMeasureType().getDescription(), + measure.getRegulationId(), + measure.getDutyRate())); + } + + if (selectedDuty != null) { + return new CustomDTO(false, selectedDuty, customMeasures, countryId); + } + + + } catch (Exception e) { + // just continue + } + + return propertyRepository.getPropertyByMappingId(SystemPropertyMappingId.TARIFF_RATE).map(PropertyDTO::getCurrentValue).map(Double::valueOf).map(d -> new CustomDTO(d, customMeasures, countryId)).orElseThrow(() -> new InternalErrorException("Unable to load default custom rate. Please contact support.")); + + } + @Async public CompletableFuture getTariffRate(String hsCode, Integer countryId) { var country = countryRepository.getById(countryId); diff --git a/src/main/java/de/avatic/lcc/service/calculation/ChangeMaterialService.java b/src/main/java/de/avatic/lcc/service/calculation/ChangeMaterialService.java index 351a058..83af4a2 100644 --- a/src/main/java/de/avatic/lcc/service/calculation/ChangeMaterialService.java +++ b/src/main/java/de/avatic/lcc/service/calculation/ChangeMaterialService.java @@ -15,6 +15,7 @@ import de.avatic.lcc.repositories.premise.PremiseRepository; import de.avatic.lcc.repositories.users.UserNodeRepository; import de.avatic.lcc.service.api.CustomApiService; import de.avatic.lcc.service.access.PremisesService; +import de.avatic.lcc.service.api.EUTaxationApiWrapperService; import de.avatic.lcc.service.users.AuthorizationService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,8 +36,9 @@ public class ChangeMaterialService { private final PackagingPropertiesRepository packagingPropertiesRepository; private final MaterialRepository materialRepository; private final AuthorizationService authorizationService; + private final EUTaxationApiWrapperService eUTaxationApiWrapperService; - public ChangeMaterialService(PremiseRepository premiseRepository, PremisesService premisesService, CustomApiService customApiService, NodeRepository nodeRepository, UserNodeRepository userNodeRepository, PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, PackagingPropertiesRepository packagingPropertiesRepository, MaterialRepository materialRepository, AuthorizationService authorizationService) { + public ChangeMaterialService(PremiseRepository premiseRepository, PremisesService premisesService, CustomApiService customApiService, NodeRepository nodeRepository, UserNodeRepository userNodeRepository, PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, PackagingPropertiesRepository packagingPropertiesRepository, MaterialRepository materialRepository, AuthorizationService authorizationService, EUTaxationApiWrapperService eUTaxationApiWrapperService) { this.premiseRepository = premiseRepository; this.premisesService = premisesService; this.customApiService = customApiService; @@ -47,6 +49,7 @@ public class ChangeMaterialService { this.packagingPropertiesRepository = packagingPropertiesRepository; this.materialRepository = materialRepository; this.authorizationService = authorizationService; + this.eUTaxationApiWrapperService = eUTaxationApiWrapperService; } @Transactional @@ -84,7 +87,7 @@ public class ChangeMaterialService { for (var premise : premisesToProcess) { var countryId = dto.isUserSupplierNode() ? userNodeRepository.getById(premise.getUserSupplierNodeId()).orElseThrow().getCountryId() : nodeRepository.getById(premise.getSupplierNodeId()).orElseThrow().getCountryId(); - var tariffRate = customApiService.getTariffRate(material.getHsCode(), countryId); + var tariffRate = eUTaxationApiWrapperService.getTariffRateImmediate(material.getHsCode(), countryId); premiseRepository.updateMaterial(Collections.singletonList(premise.getId()), material.getHsCode(), BigDecimal.valueOf(tariffRate.getValue())); if (!dto.isUserSupplierNode()) { diff --git a/src/main/java/de/avatic/lcc/service/calculation/ChangeSupplierService.java b/src/main/java/de/avatic/lcc/service/calculation/ChangeSupplierService.java index 185b06a..689cd0d 100644 --- a/src/main/java/de/avatic/lcc/service/calculation/ChangeSupplierService.java +++ b/src/main/java/de/avatic/lcc/service/calculation/ChangeSupplierService.java @@ -17,6 +17,7 @@ import de.avatic.lcc.repositories.users.UserNodeRepository; import de.avatic.lcc.service.api.CustomApiService; import de.avatic.lcc.service.access.DestinationService; import de.avatic.lcc.service.access.PremisesService; +import de.avatic.lcc.service.api.EUTaxationApiWrapperService; import de.avatic.lcc.service.users.AuthorizationService; import de.avatic.lcc.util.exception.badrequest.InvalidArgumentException; import org.springframework.stereotype.Service; @@ -42,8 +43,9 @@ public class ChangeSupplierService { private final RouteSectionRepository routeSectionRepository; private final RouteNodeRepository routeNodeRepository; private final AuthorizationService authorizationService; + private final EUTaxationApiWrapperService eUTaxationApiWrapperService; - public ChangeSupplierService(PremiseRepository premiseRepository, DestinationService destinationService, RoutingService routingService, PremisesService premisesService, CustomApiService customApiService, NodeRepository nodeRepository, UserNodeRepository userNodeRepository, PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, PackagingPropertiesRepository packagingPropertiesRepository, DestinationRepository destinationRepository, RouteRepository routeRepository, RouteSectionRepository routeSectionRepository, RouteNodeRepository routeNodeRepository, AuthorizationService authorizationService) { + public ChangeSupplierService(PremiseRepository premiseRepository, DestinationService destinationService, RoutingService routingService, PremisesService premisesService, CustomApiService customApiService, NodeRepository nodeRepository, UserNodeRepository userNodeRepository, PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, PackagingPropertiesRepository packagingPropertiesRepository, DestinationRepository destinationRepository, RouteRepository routeRepository, RouteSectionRepository routeSectionRepository, RouteNodeRepository routeNodeRepository, AuthorizationService authorizationService, EUTaxationApiWrapperService eUTaxationApiWrapperService) { this.premiseRepository = premiseRepository; this.destinationService = destinationService; this.routingService = routingService; @@ -59,6 +61,7 @@ public class ChangeSupplierService { this.routeSectionRepository = routeSectionRepository; this.routeNodeRepository = routeNodeRepository; this.authorizationService = authorizationService; + this.eUTaxationApiWrapperService = eUTaxationApiWrapperService; } @@ -110,7 +113,7 @@ public class ChangeSupplierService { //update master data: if (dto.isUpdateMasterData()) { for (var premise : premisesToProcess) { - var tariffRate = customApiService.getTariffRate(premise.getHsCode(), supplier.getCountryId()); + var tariffRate = eUTaxationApiWrapperService.getTariffRateImmediate(premise.getHsCode(), supplier.getCountryId()); premiseRepository.updateTariffRate(premise.getId(), tariffRate.getValue()); if (!dto.isUserSupplierNode()) { diff --git a/src/main/java/de/avatic/lcc/service/calculation/PremiseCreationService.java b/src/main/java/de/avatic/lcc/service/calculation/PremiseCreationService.java index 945c1ad..4cca720 100644 --- a/src/main/java/de/avatic/lcc/service/calculation/PremiseCreationService.java +++ b/src/main/java/de/avatic/lcc/service/calculation/PremiseCreationService.java @@ -15,6 +15,7 @@ import de.avatic.lcc.repositories.premise.PremiseRepository; import de.avatic.lcc.repositories.users.UserNodeRepository; import de.avatic.lcc.service.api.CustomApiService; import de.avatic.lcc.service.access.DestinationService; +import de.avatic.lcc.service.api.EUTaxationApiWrapperService; import de.avatic.lcc.service.transformer.generic.DimensionTransformer; import de.avatic.lcc.service.transformer.premise.PremiseTransformer; import de.avatic.lcc.service.users.AuthorizationService; @@ -42,8 +43,9 @@ public class PremiseCreationService { private final PackagingPropertiesRepository packagingPropertiesRepository; private final CustomApiService customApiService; private final AuthorizationService authorizationService; + private final EUTaxationApiWrapperService eUTaxationApiWrapperService; - public PremiseCreationService(PremiseRepository premiseRepository, PremiseTransformer premiseTransformer, DestinationService destinationService, UserNodeRepository userNodeRepository, NodeRepository nodeRepository, MaterialRepository materialRepository, DimensionTransformer dimensionTransformer, PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, PackagingPropertiesRepository packagingPropertiesRepository, CustomApiService customApiService, AuthorizationService authorizationService) { + public PremiseCreationService(PremiseRepository premiseRepository, PremiseTransformer premiseTransformer, DestinationService destinationService, UserNodeRepository userNodeRepository, NodeRepository nodeRepository, MaterialRepository materialRepository, DimensionTransformer dimensionTransformer, PackagingRepository packagingRepository, PackagingDimensionRepository packagingDimensionRepository, PackagingPropertiesRepository packagingPropertiesRepository, CustomApiService customApiService, AuthorizationService authorizationService, EUTaxationApiWrapperService eUTaxationApiWrapperService) { this.premiseRepository = premiseRepository; this.premiseTransformer = premiseTransformer; this.destinationService = destinationService; @@ -56,6 +58,7 @@ public class PremiseCreationService { this.packagingPropertiesRepository = packagingPropertiesRepository; this.customApiService = customApiService; this.authorizationService = authorizationService; + this.eUTaxationApiWrapperService = eUTaxationApiWrapperService; } @Transactional @@ -124,7 +127,7 @@ public class PremiseCreationService { } var material = materialRepository.getById(p.getMaterialId()); - material.ifPresent(value -> premiseRepository.updateMaterial(Collections.singletonList(p.getId()), value.getHsCode(), BigDecimal.valueOf(customApiService.getTariffRate(value.getHsCode(), getCountryId(p)).getValue()))); + material.ifPresent(value -> premiseRepository.updateMaterial(Collections.singletonList(p.getId()), value.getHsCode(), BigDecimal.valueOf(eUTaxationApiWrapperService.getTariffRateImmediate(value.getHsCode(), getCountryId(p)).getValue()))); }