package net.gepafin.tendermanagement.dao; import java.net.URI; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import feign.FeignException; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.ApplicationSignedDocumentStatusEnum; import net.gepafin.tendermanagement.enums.ProtocolTypeEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationSignedDocumentRepository; import net.gepafin.tendermanagement.service.feignClient.ProtocolService; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; 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.ResponseEntity; import org.springframework.stereotype.Component; import net.gepafin.tendermanagement.repositories.ProtocolRepository; import net.gepafin.tendermanagement.util.DateTimeUtil; @Component public class ProtocolDao { @Autowired private ProtocolRepository protocolRepository; @Value("${default.hub.uuid}") private String defaultHubUuid; @Autowired private LoggingUtil loggingUtil; @Autowired private HttpServletRequest request; @Autowired private ProtocolService protocolService; @Value("${codAoo}") private String codAoo; @Value("${sviluppumbria.username}") private String username; @Value("${password}") private String password; @Value("${CLASSIFICA}") private String classifica; @Value("${TIPO_PROTOCOLLAZIONE}") private String TIPO_PROTOCOLLAZIONE; @Value("${tipoCorrispondenteCompany}") private String tipoCorrispondenteCompany; @Value("${tipoCorrispondenteWithoutCompany}") private String tipoCorrispondenteWithoutCompany; @Value("${mezzo}") private String mezzo; @Value("${indirizzoPec}") private String indirizzoPec; @Value("${codiceUo}") private String codiceUo; @Value("${competente}") private Boolean competente; @Value("${tipoCorrispondente}") private String tipoCorrispondente; @Autowired private ApplicationSignedDocumentRepository applicationSignedDocumentRepository; public final Logger log = LoggerFactory.getLogger(ProtocolDao.class); public Long getProtocolNumber(HubEntity hubEntity) { Long maxProtocolNumber = protocolRepository.findMaxProtocolNumberAndHubId(hubEntity.getId()); Long startNumber = 10000001L; if(Boolean.FALSE.equals(defaultHubUuid.equals(hubEntity.getUniqueUuid()))) { startNumber = 20000001L; } return (maxProtocolNumber != null) ? maxProtocolNumber + 1 : startNumber; } public ProtocolEntity createProtocolEntity(ApplicationEntity applicationEntity,Long protocolNumber, Long hubId,Boolean isForApplication){ ProtocolEntity protocolEntity=new ProtocolEntity(); protocolEntity.setCall(applicationEntity.getCall().getId()); LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); protocolEntity.setYear(utcDateTime.getYear()); protocolEntity.setProtocolNumber(protocolNumber); LocalTime time = utcDateTime.toLocalTime().withNano(0); protocolEntity.setTime(time); protocolEntity.setApplicationId(applicationEntity.getId()); protocolEntity.setHubId(hubId); if(Boolean.TRUE.equals(isForApplication)){ protocolEntity.setType(ProtocolTypeEnum.INPUT.getValue()); }else { protocolEntity.setType(ProtocolTypeEnum.OUTPUT.getValue()); } return protocolEntity; } public void saveProtocolEntity(ProtocolEntity protocolEntity) { protocolRepository.save(protocolEntity); /** This code is responsible for adding a version history log for "create protocol" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(protocolEntity).build()); } public String getBearerToken(String codAoo, String username, String password) { log.info("Requesting bearer token for user: {} and codAoo: {}", username, codAoo); HttpHeaders httpHeaders = Utils.getHeaders(); URI url = URI.create(GepafinConstant.PROTOCOL_SERVICE_BEARER_TOKEN); try { ResponseEntity response = protocolService.getBearerToken(httpHeaders, codAoo,username,password); if (response != null && response.getStatusCode().is2xxSuccessful()) { log.debug("Bearer token successfully retrieved. HTTP Status: {}", response.getStatusCode()); return response.getBody().toString(); // Use getBody() instead of toString() } else { log.warn("Bearer token request failed or returned unexpected status. Response: {}", response); } } catch (FeignException ex) { log.error("FeignException while retrieving bearer token for user {}: {}", username, ex.getMessage(), ex); Utils.callException(ex.status(), ex); } catch (Exception ex) { log.error("Unexpected exception while retrieving bearer token: {}", ex.getMessage(), ex); } log.warn("Returning null bearer token for user: {}", username); return null; } public ProtocolEntity createExternalProtocol(ApplicationEntity application, CompanyEntity company, ProtocolEntity protocol) { log.info("Starting createExternalProtocol for application ID: {}", application.getId()); log.debug("Successfully retrieved bearer token"); ApplicationSignedDocumentEntity applicationSignedDocumentEntity=applicationSignedDocumentRepository.findByApplicationIdAndStatus(application.getId(), ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); String year = String.valueOf(LocalDateTime.now().getYear()); String applicationId = String.valueOf(application.getId()); String mittenteValue=""; String vatNumber =""; if(company!=null) { mittenteValue= tipoCorrispondenteCompany; vatNumber=company.getVatNumber(); }else { mittenteValue = tipoCorrispondenteWithoutCompany; vatNumber = company.getCodiceFiscale(); } String companyName = company.getCompanyName() + " " + vatNumber; String callName = application.getCall().getName()+" "+ application.getCall().getId(); String callId = GepafinConstant.PROTOCOL_CALL_NAME+ String.valueOf(application.getCall().getId()); String pecEmail=company.getPec(); String docUrl=applicationSignedDocumentEntity.getFilePath()+GepafinConstant.PROTOCOL_DOC_SUFFIX; Map requestBody = new HashMap<>(); requestBody.put(GepafinConstant.PROTOCOL_DOC_URL,docUrl); requestBody.put(GepafinConstant.PROTOCOL_COMPANY_NAME,companyName); requestBody.put(GepafinConstant.PROTOCOL_DOC_HASH,applicationSignedDocumentEntity.getFileHash()); requestBody.put(GepafinConstant.PROTOCOL_TIPO_PROTOCOLLAZIONE,TIPO_PROTOCOLLAZIONE); Map mittente = new HashMap<>(); mittente.put(GepafinConstant.PROTOCOL_TIPO_CORRISPONDENTE_COMPANY, mittenteValue); mittente.put(GepafinConstant.PROTOCOL_COMPANY_NAME_VAT_NUMBER,company.getCompanyName()); mittente.put(GepafinConstant.PROTOCOL_MEZZO,mezzo); mittente.put(GepafinConstant.PROTOCOL_INDIRIZZO_PEC,pecEmail); mittente.put(GepafinConstant.PROTOCOL_COMPANY_VAT_NUMBER,vatNumber); List> destinatariObject=new ArrayList<>(); Map destinatari = new HashMap<>(); destinatari.put(GepafinConstant.PROTOCOL_CODICE_UO,codiceUo); destinatari.put(GepafinConstant.PROTOCOL_COMPETENTE,competente); destinatari.put(GepafinConstant.PROTOCOL_TIPO_CORRISPONDENTE,tipoCorrispondente); requestBody.put(GepafinConstant.PROTOCOL_MITTENTE,mittente); destinatariObject.add(destinatari); requestBody.put(GepafinConstant.PROTOCOL_DESTINATARI,destinatariObject); List> listObject=new ArrayList<>(); listObject.add(requestBody); log.info("Preparing to create protocol with data: year={}, applicationId={}, companyName={}, callName={}, callId={}", year, applicationId, companyName, callName, callId); ResponseEntity response=null; try { String bearerToken = getBearerToken(codAoo, username, password); if (bearerToken == null) { log.error("Bearer token retrieval failed for user: {}", username); return protocol; } HttpHeaders httpHeaders = Utils.getHeaders(); httpHeaders.set(GepafinConstant.AUTHORIZATION, "Bearer " + bearerToken); URI url = URI.create(GepafinConstant.PROTOCOL_SERVICE_CREATE_PROTOCOL); response = protocolService.createProtocol(httpHeaders, classifica, year, applicationId, companyName, callName, callId,listObject ); log.info("Protocol creation response: status={}, body={}", response.getStatusCode(), response.getBody()); } catch (FeignException ex) { log.error("FeignException during protocol creation for application ID {}: {}", applicationId, ex.getMessage(), ex); // Utils.callException(ex.status(), ex); } catch (Exception ex) { log.error("Unexpected exception during protocol creation for application ID {}: {}", applicationId, ex.getMessage(), ex); } log.info("Finished createExternalProtocol for application ID: {}", application.getId()); if(response!=null && response.getBody()!=null) { protocol = extractDetailForProtocol((List>) response.getBody(), protocol); } return protocol; } public ProtocolEntity extractDetailForProtocol(List> responseObject, ProtocolEntity protocol) { Map responseField= responseObject.get(0); Object yearObj = responseField.get(GepafinConstant.PROTOCOL_EXTERNAL_YEAR); Integer externalProtocolYear = null; if (yearObj instanceof Integer) { externalProtocolYear = (Integer) yearObj; } else if (yearObj instanceof String) { try { externalProtocolYear = Integer.parseInt((String) yearObj); } catch (NumberFormatException e) { // handle invalid format gracefully externalProtocolYear = null; } } Object dateObj = responseField.get(GepafinConstant.PROTOCOL_EXTERNAL_DATE); LocalDateTime externalProtocolDate = null; if (dateObj instanceof LocalDateTime) { externalProtocolDate = (LocalDateTime) dateObj; } else if (dateObj instanceof String) { externalProtocolDate = DateTimeUtil.parseStringToLocalDateTime((String) dateObj); } if(externalProtocolDate!=null){ protocol.setExternalProtocolDate(externalProtocolDate); } if (externalProtocolYear!=null){ protocol.setExternalProtocolYear(externalProtocolYear); } String externalProtocolNumber = (String) responseField.get(GepafinConstant.PROTOCOL_EXTERNAL_NUMBER); if (Boolean.FALSE.equals(StringUtils.isEmpty(externalProtocolNumber))) { protocol.setExternalProtocolNumber(externalProtocolNumber); } protocolRepository.save(protocol); return protocol; } }