package net.gepafin.tendermanagement.dao; import feign.FeignException; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.CompanyEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.VatCheckVersionTypeEnum; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; import net.gepafin.tendermanagement.repositories.CompanyRepository; import net.gepafin.tendermanagement.repositories.GlobalConfigRepository; import net.gepafin.tendermanagement.service.feignClient.VatCheckV1Service; import net.gepafin.tendermanagement.service.feignClient.VatCheckV2Service; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @Component public class VatCheckDao { @Autowired private VatCheckV2Service vatCheckV2Service; @Autowired private VatCheckV1Service vatCheckV1Service; @Value("${vatCheckTokenV2}") public String vatCheckTokenV2; @Value("${vatCheckTokenV1}") public String vatCheckTokenV1; @Value("${isVatCheckGloballyDisabled}") public String isVatCheckGloballyDisabled; @Autowired private GlobalConfigRepository globalConfigRepository; @Autowired private CompanyRepository companyRepository; public final Logger log = LoggerFactory.getLogger(VatCheckDao.class); public VatCheckResponseBean checkVatNumberV1(String vatNumber) { VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); vatCheckResponseBean.setValid(false); vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); if (Boolean.TRUE.equals(Boolean.parseBoolean(isVatCheckGloballyDisabled))) { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); vatCheckResponseBean.setVersion(VatCheckVersionTypeEnum.V1); return vatCheckResponseBean; } try { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_JSON); headers.set(GepafinConstant.AUTHORIZATION, "Bearer " + vatCheckTokenV1); headers.add(org.apache.http.HttpHeaders.USER_AGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"); URI baseUrl = URI.create(GepafinConstant.CHECK_VATNUMBER_URL_V1); ResponseEntity> response = vatCheckV1Service.checkVatNumber(baseUrl, vatNumber, headers); if (response.getStatusCode() == HttpStatus.OK && response.hasBody()) { logSuccess(); Map responseMap = response.getBody(); if (responseMap != null) { processValidResponseV1(responseMap, vatCheckResponseBean); } else { log.warn("Response map or vatCheckResponseBean is null."); } } } catch (FeignException ex) { if (ex.status() == 406) { try { Map errorResponse = Utils.parseErrorResponse(ex.contentUTF8()); processValidResponseV1(errorResponse, vatCheckResponseBean); } catch (Exception parseEx) { log.error("Failed to parse 406 error response: {0}", parseEx); } } else { log.error("Exception occurred while checking vat number: {0}", ex); Utils.callException(ex.status(), ex); } } return vatCheckResponseBean; } public static void processValidResponseV1(Map responseMap, VatCheckResponseBean vatCheckResponseBean) { Object dataObj = responseMap.get("data"); vatCheckResponseBean.setVersion(VatCheckVersionTypeEnum.V1); if (dataObj instanceof Map rawDataMap) { Map responseBody = new LinkedHashMap<>(); rawDataMap.forEach((k, v) -> { if (k instanceof String strKey) { responseBody.put(strKey, v); } }); List.of("timestamp_creation", "timestamp_last_update", "id", "data_iscrizione").forEach(responseBody.keySet()::remove); Map data = new LinkedHashMap<>(); data.put("data", responseBody); vatCheckResponseBean.setValid(true); vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); vatCheckResponseBean.setVatCheckResponse(data); } else { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); } } public VatCheckResponseBean checkVatNumber(String vatNumber, Long hubId) { try { CompanyEntity company = companyRepository.findByVatNumberAndHubId(vatNumber, hubId); if (company != null && Boolean.FALSE.equals(StringUtils.isEmpty(company.getJson()))) { Map responseMap = Utils.convertJsonStringToMap(company.getJson()); VatCheckResponseBean jsonResponse = validateJsonFromDb(responseMap); if (jsonResponse != null) { return jsonResponse; } } String vatApiVersion = getVatCheckVersion(); if(!isVatCheckApiV2(vatApiVersion)){ return checkVatNumberV1(vatNumber); } return checkVatNumberV2(vatNumber); } catch (Exception e) { logErrorMessage(e); VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); vatCheckResponseBean.setValid(false); vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); return vatCheckResponseBean; } } private VatCheckResponseBean validateJsonFromDb(Map responseMap) { if (responseMap == null || !responseMap.containsKey("data")) return null; Object data = responseMap.get("data"); if (data instanceof Map dataMap && !dataMap.isEmpty()) { VatCheckResponseBean response = new VatCheckResponseBean(); processValidResponseV1(responseMap, response); return response; } if (data instanceof List dataList && !dataList.isEmpty()) { VatCheckResponseBean response = new VatCheckResponseBean(); processValidResponse(responseMap, response); return response; } return null; } public VatCheckResponseBean checkVatNumberV2(String vatNumber) { VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); vatCheckResponseBean.setValid(false); vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); if (Boolean.TRUE.equals(Boolean.parseBoolean(isVatCheckGloballyDisabled))) { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); vatCheckResponseBean.setVersion(VatCheckVersionTypeEnum.V2); return vatCheckResponseBean; } try { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.set(GepafinConstant.AUTHORIZATION, "Bearer " + vatCheckTokenV2); URI baseUrl = URI.create(GepafinConstant.CHECK_VATNUMBER_URL_V2); ResponseEntity> response = vatCheckV2Service.checkVatNumber(baseUrl, vatNumber, headers); if (response.getStatusCode() == HttpStatus.OK && response.hasBody()) { logSuccess(); Map responseMap = response.getBody(); processValidResponse(responseMap, vatCheckResponseBean); } } catch (FeignException ex) { if (ex.status() == 406) { try { Map errorResponse = Utils.parseErrorResponse(ex.contentUTF8()); processValidResponse(errorResponse, vatCheckResponseBean); } catch (Exception parseEx) { log.error("Failed to parse 406 error response: {0}", parseEx); } } else { log.error("Exception occurred while checking vat number: {0}", ex); Utils.callException(ex.status(), ex); } } return vatCheckResponseBean; } public static void processValidResponse(Map responseMap, VatCheckResponseBean vatCheckResponseBean) { vatCheckResponseBean.setVersion(VatCheckVersionTypeEnum.V2); if (responseMap == null || !responseMap.containsKey("data")) { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); return; } Object dataObject = responseMap.get("data"); if (!(dataObject instanceof List dataList) || dataList.isEmpty()) { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); return; } List> processedList = new ArrayList<>(); for (Object item : dataList) { if (item instanceof Map mapItem) { Map responseBody = new LinkedHashMap<>(); mapItem.forEach((key, value) -> { if (key instanceof String strKey) { responseBody.put(strKey, value); } }); List.of("creationTimestamp", "lastUpdateTimestamp", "id").forEach(responseBody.keySet()::remove); processedList.add(responseBody); } } if (processedList.isEmpty()) { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); return; } vatCheckResponseBean.setValid(true); vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); vatCheckResponseBean.setVatCheckResponse(Map.of("data", processedList)); } private void logSuccess() { log.info("Successfully checked vat number"); } private static boolean isVatCheckApiV2(String vatApiVersion) { boolean isNotBlank = StringUtils.isNotBlank(vatApiVersion); boolean isNotEmpty = StringUtils.isNotEmpty(vatApiVersion); return isNotBlank && isNotEmpty && Boolean.TRUE.equals(vatApiVersion.equals(VatCheckVersionTypeEnum.V2.getValue())); } private String getVatCheckVersion() { return globalConfigRepository.findContentByTypeAndIsDeletedFalse(GepafinConstant.VAT_CHECK_API_VERSION); } private void logErrorMessage(Exception e) { log.error("Error in checkVatNumber: {}", e.getMessage()); } }