Enhance tariff services with custom preference logic, internal error handling, and repository integration updates.

This commit is contained in:
Jan 2025-11-02 22:09:37 +01:00
parent ce79b20808
commit b8b8b2b5e9
5 changed files with 47 additions and 16 deletions

View file

@ -20,7 +20,7 @@ public class TariffController {
@GetMapping("") @GetMapping("")
public ResponseEntity<Double> getTariffRate(@RequestParam String hsCode, @RequestParam String countryCode) { public ResponseEntity<Double> getTariffRate(@RequestParam String hsCode, @RequestParam String countryCode) {
return tariffService.importTariffs( hsCode, countryCode).map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()); return tariffService.getCustomPref( hsCode, countryCode).map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
} }
} }

View file

@ -19,4 +19,13 @@ public class ErrorController {
dto.setMessage("Invalid argument"); dto.setMessage("Invalid argument");
return new ResponseEntity<>(dto, HttpStatus.BAD_REQUEST); return new ResponseEntity<>(dto, HttpStatus.BAD_REQUEST);
} }
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler
public ResponseEntity<ErrorDTO> handleException(InternalError ex) {
var dto = new ErrorDTO();
dto.setField(ex.getArg());
dto.setMessage("Internal error");
return new ResponseEntity<>(dto, HttpStatus.INTERNAL_SERVER_ERROR);
}
} }

View file

@ -0,0 +1,14 @@
package de.avatic.taric.error;
import lombok.Getter;
@Getter
public class InternalError extends RuntimeException {
private final String arg;
public InternalError(String arg) {
super();
this.arg = arg;
}
}

View file

@ -1,6 +1,7 @@
package de.avatic.taric.repository; package de.avatic.taric.repository;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Optional;
import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
@ -11,5 +12,5 @@ import de.avatic.taric.model.Measure;
public interface MeasureRepository extends CrudRepository<Measure, Integer> { public interface MeasureRepository extends CrudRepository<Measure, Integer> {
Optional<Measure> getMeasureByShortDesc(String pref);
} }

View file

@ -2,16 +2,13 @@ package de.avatic.taric.service;
import de.avatic.taric.error.ArgumentException; import de.avatic.taric.error.ArgumentException;
import de.avatic.taric.model.AppliedMeasure; import de.avatic.taric.model.*;
import de.avatic.taric.model.Geo;
import de.avatic.taric.model.GeoGroup;
import de.avatic.taric.model.Nomenclature;
import de.avatic.taric.repository.ImportRepository; import de.avatic.taric.repository.ImportRepository;
import de.avatic.taric.repository.MeasureRepository;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Service @Service
@Slf4j @Slf4j
@ -20,14 +17,16 @@ public class TariffService {
private final GeoService geoService; private final GeoService geoService;
private final NomenclatureService nomenclatureService; private final NomenclatureService nomenclatureService;
private final ImportRepository importRepository; private final ImportRepository importRepository;
private final MeasureRepository measureRepository;
public TariffService(GeoService geoService, NomenclatureService nomenclatureService, ImportRepository importRepository) { public TariffService(GeoService geoService, NomenclatureService nomenclatureService, ImportRepository importRepository, MeasureRepository measureRepository) {
this.geoService = geoService; this.geoService = geoService;
this.nomenclatureService = nomenclatureService; this.nomenclatureService = nomenclatureService;
this.importRepository = importRepository; this.importRepository = importRepository;
this.measureRepository = measureRepository;
} }
public Optional<Double> importTariffs(String hsCode, String countryCode) { public Optional<Double> getCustomPref(String hsCode, String countryCode) {
var geoGroups = geoService.getGeoGroupByCountryCode(countryCode); var geoGroups = geoService.getGeoGroupByCountryCode(countryCode);
var geo = geoService.getGeo(countryCode); var geo = geoService.getGeo(countryCode);
@ -35,15 +34,19 @@ public class TariffService {
var nomenclature = nomenclatureService.getNomenclature(hsCode); var nomenclature = nomenclatureService.getNomenclature(hsCode);
var cascade = nomenclatureService.getNomenclatureCascade(hsCode); var cascade = nomenclatureService.getNomenclatureCascade(hsCode);
var customAppl = measureRepository.getMeasureByShortDesc("APPL");
if (nomenclature.isEmpty() || !nomenclature.get().getIsLeaf()) throw new ArgumentException("hsCode"); if (nomenclature.isEmpty() || !nomenclature.get().getIsLeaf()) throw new ArgumentException("hsCode");
if (geo.isEmpty()) throw new ArgumentException("countryCode"); if (geo.isEmpty()) throw new ArgumentException("countryCode");
if (customAppl.isEmpty()) throw new InternalError("APPL not found");
for (Nomenclature n : cascade) { for (Nomenclature n : cascade) {
var applMeasures = findAppliedMeasureByGeo(n, geo.get()); var applMeasures = findAppliedMeasureByGeo(n, geo.get());
if (!applMeasures.isEmpty()) { if (!applMeasures.isEmpty()) {
var tariff = findTariff(applMeasures); var tariff = findTariff(applMeasures, customAppl.get());
if (tariff.isPresent()) if (tariff.isPresent())
return tariff; return tariff;
@ -56,7 +59,7 @@ public class TariffService {
var applMeasures = findAppliedMeasureByGeoGroup(n, geo.get(), geoGroups); var applMeasures = findAppliedMeasureByGeoGroup(n, geo.get(), geoGroups);
if (!applMeasures.isEmpty()) { if (!applMeasures.isEmpty()) {
var tariff = findTariff(applMeasures); var tariff = findTariff(applMeasures, customAppl.get());
if (tariff.isPresent()) if (tariff.isPresent())
return tariff; return tariff;
@ -67,14 +70,18 @@ public class TariffService {
} }
private Optional<Double> findTariff(Collection<AppliedMeasure> measures) { private Optional<Double> findTariff(Collection<AppliedMeasure> measures, Measure appl) {
List<Double> percentages = measures.stream().map(AppliedMeasure::getAmount) var code = appl.getMeasureCode();
.filter(str -> str != null && str.trim().matches("\\d+\\.\\d+\\s*%"))
.map(str -> Double.parseDouble(str.trim().replace("%", "").trim())/100)
List<AppliedMeasure> filteredMeasures = measures.stream()
.filter(meas -> meas.getAmount() != null && meas.getAmount().trim().matches("\\d+\\.\\d+\\s*%"))
.toList(); .toList();
if (!percentages.isEmpty()) return Optional.of(percentages.getFirst()); AppliedMeasure customTariff = filteredMeasures.stream().filter(meas -> meas.getMeasure().getId().equals(appl.getId())).findAny().orElse(filteredMeasures.isEmpty() ? null : filteredMeasures.getFirst());
if (!filteredMeasures.isEmpty()) return Optional.of(customTariff).map(meas -> Double.parseDouble(meas.getAmount().trim().replace("%", "").trim())/100);
return Optional.empty(); return Optional.empty();
} }