Resolved conflict
This commit is contained in:
@@ -18,7 +18,7 @@ public class AppointmentApiConstant {
|
||||
public static final boolean CREA_ANAGRAFICA = Boolean.TRUE;
|
||||
public static final boolean SALVA_DOCUMENTI = Boolean.TRUE;
|
||||
public static final String VISURA_PROVIDER = "cerved";
|
||||
public static final String VISURA_TYPE = "StandardReport";
|
||||
public static final String VISURA_TYPE = "FullReport";
|
||||
public static final String VISURA_MODE = "visure";
|
||||
public static final String COD_AGENTE = "UtenzaAPIPortal";
|
||||
public static final boolean IS_FROM_RATING = Boolean.FALSE;
|
||||
@@ -38,4 +38,7 @@ public class AppointmentApiConstant {
|
||||
public static final String COD_OPERAZIONE = "codOperazione";
|
||||
public static final String MOTIVAZIONE_ID = "id";
|
||||
public static final String PRODOTTO_CODE = "code";
|
||||
|
||||
public static final String WS_ANAGRAFICA_URL= "/WSAnagrafica.getList";
|
||||
|
||||
}
|
||||
|
||||
@@ -571,7 +571,9 @@ public class GepafinConstant {
|
||||
public static final String PROTOCOL_EXTERNAL_NUMBER="NUM_PG";
|
||||
public static final String PROTOCOL_EXTERNAL_DATE="DATA_PG_DT";
|
||||
public static final String PROTOCOL_DOC_SUFFIX="#noauth";
|
||||
|
||||
public static final String CREATE_NDG="CHECK_OR_CREATE_NDG_CODE";
|
||||
public static final String NDG_NOT_FOUND="ndg.not.found";
|
||||
public static final String EMAIL_PEC_REQUIRED="email.pec.cannot.null";
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.gepafin.tendermanagement.dao;
|
||||
|
||||
import com.amazonaws.services.dynamodbv2.xspec.S;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -556,15 +557,47 @@ public class ApplicationDao {
|
||||
VersionActionTypeEnum actionType = VersionActionTypeEnum.INSERT;
|
||||
List<ContentResponseBean> contentResponseBeans = formDao.convertFormEntityToFormResponseBean(formEntity).getContent();
|
||||
|
||||
// contentResponseBeans.stream()
|
||||
// .filter(content -> "numberinput".equals(content.getName()) && content.getId().toString().equals(applicationFormFieldRequestBean.getFieldId()))
|
||||
// .map(ContentResponseBean::getSettings)
|
||||
// .flatMap(List::stream)
|
||||
// .filter(setting -> "isRequestedAmount".equals(setting.getName()) && Boolean.TRUE.equals(setting.getValue()))
|
||||
// .findFirst()
|
||||
// .ifPresent(setting -> {
|
||||
// Object fieldValue = applicationFormFieldRequestBean.getFieldValue();
|
||||
// if(fieldValue!=null) {
|
||||
// try {
|
||||
// BigDecimal amountRequested = new BigDecimal(fieldValue.toString());
|
||||
// applicationFormEntity.getApplication().setAmountRequested(amountRequested);
|
||||
// log.info("Set amountRequested to {} for Application ID: {}", amountRequested, applicationFormEntity.getApplication().getId());
|
||||
// } catch (NumberFormatException e) {
|
||||
// log.error("Invalid number format for requested amount: {}", fieldValue, e);
|
||||
// throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
contentResponseBeans.stream()
|
||||
.filter(content -> "numberinput".equals(content.getName()) && content.getId().toString().equals(applicationFormFieldRequestBean.getFieldId()))
|
||||
.map(ContentResponseBean::getSettings)
|
||||
.flatMap(List::stream)
|
||||
.filter(setting -> "isRequestedAmount".equals(setting.getName()) && Boolean.TRUE.equals(setting.getValue()))
|
||||
.filter(content -> content.getId().toString().equals(applicationFormFieldRequestBean.getFieldId()))
|
||||
.findFirst()
|
||||
.ifPresent(setting -> {
|
||||
.ifPresent(content -> {
|
||||
Object fieldValue = applicationFormFieldRequestBean.getFieldValue();
|
||||
if(fieldValue!=null) {
|
||||
if (fieldValue == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert settings list to a map
|
||||
Map<String, Object> settingMap = content.getSettings().stream()
|
||||
.collect(Collectors.toMap(SettingResponseBean::getName, SettingResponseBean::getValue, (v1, v2) -> v1));
|
||||
|
||||
String fieldType = content.getName();
|
||||
|
||||
// Define handlers for different (fieldType + settingName) combinations
|
||||
Map<String, Runnable> handlers = new HashMap<>();
|
||||
|
||||
// Add handler for isRequestedAmount
|
||||
if ("numberinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isRequestedAmount"))) {
|
||||
handlers.put("isRequestedAmount", () -> {
|
||||
try {
|
||||
BigDecimal amountRequested = new BigDecimal(fieldValue.toString());
|
||||
applicationFormEntity.getApplication().setAmountRequested(amountRequested);
|
||||
@@ -573,7 +606,19 @@ public class ApplicationDao {
|
||||
log.error("Invalid number format for requested amount: {}", fieldValue, e);
|
||||
throw new IllegalArgumentException("Field value is not a valid number: " + fieldValue, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Add handler for isPecEmail
|
||||
if ("textinput".equals(fieldType) && Boolean.TRUE.equals(settingMap.get("isPecEmail"))) {
|
||||
handlers.put("isPecEmail", () -> {
|
||||
applicationFormEntity.getApplication().setPecEmail(fieldValue.toString());
|
||||
log.info("Set PEC to {} for Application ID: {}", fieldValue, applicationFormEntity.getApplication().getId());
|
||||
});
|
||||
}
|
||||
|
||||
// Run all applicable handlers
|
||||
handlers.values().forEach(Runnable::run);
|
||||
});
|
||||
|
||||
|
||||
@@ -1158,8 +1203,16 @@ public class ApplicationDao {
|
||||
// Create the map for body placeholders
|
||||
Map<String, String> bodyPlaceholders = new HashMap<>();
|
||||
bodyPlaceholders.put("{{call_name}}", call.getName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString());
|
||||
bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY));
|
||||
String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber());
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_number}}",protocolNumber);
|
||||
String protocolDate= DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY);
|
||||
if(protocol.getExternalProtocolDate()!=null){
|
||||
protocolDate= DateTimeUtil.formatLocalDateTime(protocol.getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY);
|
||||
}
|
||||
bodyPlaceholders.put("{{date}}", protocolDate);
|
||||
bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS));
|
||||
|
||||
// Replace placeholders in the subject and body
|
||||
@@ -1209,8 +1262,17 @@ public class ApplicationDao {
|
||||
// Create the map for body placeholders
|
||||
Map<String, String> bodyPlaceholders = new HashMap<>();
|
||||
bodyPlaceholders.put("{{call_name}}", call.getName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocol.getProtocolNumber().toString());
|
||||
bodyPlaceholders.put("{{date}}", DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY));
|
||||
String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber();
|
||||
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber());
|
||||
}
|
||||
String protocolDate= DateTimeUtil.formatLocalDateTime(protocol.getCreatedDate(), GepafinConstant.DD_MM_YYYY);
|
||||
if(protocol.getExternalProtocolDate()!=null){
|
||||
protocolDate= DateTimeUtil.formatLocalDateTime(protocol.getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY);
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocolNumber);
|
||||
bodyPlaceholders.put("{{date}}",protocolDate);
|
||||
bodyPlaceholders.put("{{time}}", DateTimeUtil.parseLocalTimeToString(protocol.getTime(), GepafinConstant.HH_MM_SS));
|
||||
|
||||
// Replace placeholders in the subject and body
|
||||
@@ -2328,7 +2390,11 @@ public class ApplicationDao {
|
||||
bodyPlaceholders.put("{{call_name}}", call.getName());
|
||||
bodyPlaceholders.put("{{application_id}}", applicationEntity.getId().toString());
|
||||
bodyPlaceholders.put("{{company_name}}", company.getCompanyName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", applicationEntity.getProtocol().getProtocolNumber().toString());
|
||||
String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber());
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocolNumber);
|
||||
bodyPlaceholders.put("{{user_action_id}}",emailLogRequest.getUserActionId().toString());
|
||||
|
||||
String subject = Utils.replacePlaceholders(systemEmailTemplateResponse.getSubject(), subjectPlaceholders);
|
||||
|
||||
@@ -710,7 +710,11 @@ public class ApplicationEvaluationDao {
|
||||
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||
placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
String protocolNumber=application.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(application.getProtocol().getProtocolNumber());
|
||||
}
|
||||
placeHolders.put("{{protocol_number}}", protocolNumber);
|
||||
notificationDao.sendNotificationToSuperUser(application,placeHolders,NotificationTypeEnum.EVALUATION_CREATION);
|
||||
notificationDao.sendNotificationToInstructor(placeHolders,entity,NotificationTypeEnum.EVALUATION_CREATION);
|
||||
|
||||
@@ -1997,7 +2001,11 @@ public class ApplicationEvaluationDao {
|
||||
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||
placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
String protocolNumber=application.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(application.getProtocol().getProtocolNumber());
|
||||
}
|
||||
placeHolders.put("{{protocol_number}}", protocolNumber);
|
||||
notificationDao.sendNotificationToSuperUser(application,placeHolders,NotificationTypeEnum.EVALUATION_RESULT);
|
||||
notificationDao.sendNotificationToInstructor(placeHolders,existingEntity,NotificationTypeEnum.EVALUATION_RESULT);
|
||||
|
||||
|
||||
@@ -12,16 +12,8 @@ import net.gepafin.tendermanagement.config.Translator;
|
||||
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
|
||||
import net.gepafin.tendermanagement.constants.AppointmentApiConstant;
|
||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||
import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity;
|
||||
import net.gepafin.tendermanagement.entities.ApplicationEntity;
|
||||
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
|
||||
import net.gepafin.tendermanagement.entities.CompanyEntity;
|
||||
import net.gepafin.tendermanagement.entities.DocumentEntity;
|
||||
import net.gepafin.tendermanagement.entities.HubEntity;
|
||||
import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum;
|
||||
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
|
||||
import net.gepafin.tendermanagement.enums.NotificationTypeEnum;
|
||||
import net.gepafin.tendermanagement.enums.VersionActionTypeEnum;
|
||||
import net.gepafin.tendermanagement.entities.*;
|
||||
import net.gepafin.tendermanagement.enums.*;
|
||||
import net.gepafin.tendermanagement.model.request.AppointmentCreationRequest;
|
||||
import net.gepafin.tendermanagement.model.request.AppointmentNdgRequest;
|
||||
import net.gepafin.tendermanagement.model.request.AppointmentVisuraListRequest;
|
||||
@@ -33,11 +25,7 @@ import net.gepafin.tendermanagement.model.response.AppointmentCreationResponse;
|
||||
import net.gepafin.tendermanagement.model.response.AppointmentLoginResponse;
|
||||
import net.gepafin.tendermanagement.model.response.DocumentUploadResponse;
|
||||
import net.gepafin.tendermanagement.model.response.NdgResponse;
|
||||
import net.gepafin.tendermanagement.repositories.ApplicationRepository;
|
||||
import net.gepafin.tendermanagement.repositories.CompanyRepository;
|
||||
import net.gepafin.tendermanagement.repositories.DocumentRepository;
|
||||
import net.gepafin.tendermanagement.repositories.HubRepository;
|
||||
import net.gepafin.tendermanagement.repositories.UserRepository;
|
||||
import net.gepafin.tendermanagement.repositories.*;
|
||||
import net.gepafin.tendermanagement.service.AmazonS3Service;
|
||||
import net.gepafin.tendermanagement.service.ApplicationService;
|
||||
import net.gepafin.tendermanagement.service.CompanyService;
|
||||
@@ -55,6 +43,8 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
@@ -63,10 +53,8 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -150,7 +138,11 @@ public class AppointmentDao {
|
||||
@Autowired
|
||||
private ApplicationEvaluationDao applicationEvaluationDao;
|
||||
|
||||
private final Map<Long, ExecutorService> executorMap = new ConcurrentHashMap<>();
|
||||
@Autowired
|
||||
private NdganagRepository ndganagRepository;
|
||||
|
||||
private final Map<Long, ScheduledExecutorService> executorMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
private final ConcurrentHashMap<Long, ExecutorService> threadForDocumentMap = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -159,6 +151,8 @@ public class AppointmentDao {
|
||||
public NdgResponse checkNdgForAppointment(Long applicationId) {
|
||||
log.info("Starting NDG check for appointment. applicationId: {}", applicationId);
|
||||
ApplicationEntity application = applicationService.validateApplication(applicationId);
|
||||
ApplicationEntity oldApplication = Utils.getClonedEntityForData(application);
|
||||
|
||||
NdgResponse ndgResponse = new NdgResponse();
|
||||
if (application.getNdgStatus() != null && application.getNdgStatus().equalsIgnoreCase(GepafinConstant.NDG_IN_PROGRESS)) {
|
||||
log.warn("NDG generation already in progress. applicationId: {}", applicationId);
|
||||
@@ -172,9 +166,13 @@ public class AppointmentDao {
|
||||
|
||||
// Update application status
|
||||
log.info("Updating NDG status to IN_PROGRESS. applicationId: {}", applicationId);
|
||||
application.setNdgStatus(GepafinConstant.NDG_IN_PROGRESS);
|
||||
application.setNdgStatus(NdgStatusEnum.NDG_INITITATED.getValue());
|
||||
applicationRepository.save(application);
|
||||
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplication).newData(application).build());
|
||||
|
||||
|
||||
// Start async processing
|
||||
HubEntity hub = hubRepository.findByHubId(application.getHubId());
|
||||
loginToOdessa(hub, application);
|
||||
@@ -392,6 +390,7 @@ public class AppointmentDao {
|
||||
}
|
||||
throw new RuntimeException("Max retries exceeded. Failed to login to Odessa.");
|
||||
}
|
||||
|
||||
private void CheckPasswordExpiredOrErrorInResponse(ApplicationEntity application, FeignException.Forbidden forbiddenException) {
|
||||
|
||||
String responseBody = forbiddenException.contentUTF8();
|
||||
@@ -427,48 +426,103 @@ public class AppointmentDao {
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Unexpected exception during Odessa login.Error: {}",e.getMessage(), e);
|
||||
log.error("Unexpected exception during Odessa login.Error: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void startAsyncNdgProcessing(Long applicationId) {
|
||||
// Check if a thread is already running for this application
|
||||
if (executorMap.containsKey(applicationId)) {
|
||||
log.warn("Async processing already running for applicationId: {}", applicationId);
|
||||
return;
|
||||
// private void startAsyncNdgProcessing(Long applicationId) {
|
||||
// // If already polling for this applicationId, do nothing:
|
||||
// if (executorMap.containsKey(applicationId)) {
|
||||
// log.warn("Async processing already running for applicationId: {}", applicationId);
|
||||
// return;
|
||||
// }
|
||||
// ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||
//
|
||||
// ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(runnable -> {
|
||||
// Thread t = new Thread(runnable);
|
||||
// t.setName("AsyncNdgProcessing-" + applicationId);
|
||||
// return t;
|
||||
// });
|
||||
// executorMap.put(applicationId, scheduler);
|
||||
//
|
||||
// // Record the start time so we can stop after 2 hours:
|
||||
// long startTime = System.currentTimeMillis();
|
||||
// long twoHoursMs = TimeUnit.HOURS.toMillis(2);
|
||||
// long fifteenMin = 15; // in MINUTES
|
||||
//
|
||||
// // We need a reference to cancel the scheduled task from inside itself when we're done:
|
||||
// AtomicReference<ScheduledFuture<?>> futureRef = new AtomicReference<>();
|
||||
//
|
||||
// Runnable pollingTask = () -> {
|
||||
// RequestContextHolder.setRequestAttributes(requestAttributes, true);
|
||||
// Utils.setHttpServletRequestForThread(request,HttpMethodEnum.POST.getValue(),GepafinConstant.CREATE_NDG, (Long) request.getAttribute(GepafinConstant.USER_ACTION_ID));
|
||||
// try {
|
||||
// // 1) If 2 hours have already passed, mark as FAILED and shut down:
|
||||
// if (System.currentTimeMillis() - startTime > twoHoursMs) {
|
||||
// ApplicationEntity app = applicationService.validateApplication(applicationId);
|
||||
// log.warn("2-hour timeout reached for applicationId {}. Marking NDG_FAILED.", applicationId);
|
||||
// app.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||
// applicationRepository.save(app);
|
||||
//
|
||||
// futureRef.get().cancel(false);
|
||||
// shutdownScheduler(applicationId);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 2) Otherwise, call processNdgGeneration once:
|
||||
// processNdgGeneration(applicationId);
|
||||
//
|
||||
// // 3) After return, check if NDG is now set or timed out. If so, cancel & shut down:
|
||||
// ApplicationEntity updated = applicationService.validateApplication(applicationId);
|
||||
// if (isNdgValid(updated.getNdg())) {
|
||||
// log.info("NDG found for applicationId {}. Shutting down scheduler.", applicationId);
|
||||
// futureRef.get().cancel(false);
|
||||
// shutdownScheduler(applicationId);
|
||||
// } else if (updated.getNdgStatus() != null && updated.getNdgStatus().equals(GepafinConstant.NDG_FAILED)) {
|
||||
// log.info("NDG status is NDG_FAILED for applicationId {}. Shutting down scheduler.", applicationId);
|
||||
// futureRef.get().cancel(false);
|
||||
// shutdownScheduler(applicationId);
|
||||
// }
|
||||
// // Otherwise: no NDG yet, not timed out → next run happens in 15 minutes automatically.
|
||||
// } catch (Exception ex) {
|
||||
// log.error("Unexpected error during scheduled polling for applicationId {}: {}", applicationId, ex.getMessage(), ex);
|
||||
// try {
|
||||
// ApplicationEntity checkApp = applicationService.validateApplication(applicationId);
|
||||
// if (System.currentTimeMillis() - startTime > twoHoursMs) {
|
||||
// log.warn("After exception, 2-hour window passed for applicationId {}. Marking NDG_FAILED.", applicationId);
|
||||
// checkApp.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||
// applicationRepository.save(checkApp);
|
||||
//
|
||||
// futureRef.get().cancel(false);
|
||||
// shutdownScheduler(applicationId);
|
||||
// }
|
||||
// } catch (Exception ignore) {
|
||||
// futureRef.get().cancel(false);
|
||||
// shutdownScheduler(applicationId);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// // Schedule pollingTask: run now (delay=0), then every fifteen minutes:
|
||||
// ScheduledFuture<?> future = scheduler.scheduleWithFixedDelay(pollingTask, 0, // initial delay = 0 min → run immediately
|
||||
// fifteenMin, // subsequent runs every 15 minutes
|
||||
// TimeUnit.MINUTES);
|
||||
// futureRef.set(future);
|
||||
// }
|
||||
|
||||
private void shutdownScheduler(Long applicationId) {
|
||||
|
||||
ScheduledExecutorService shed = executorMap.remove(applicationId);
|
||||
if (shed != null) {
|
||||
shed.shutdownNow();
|
||||
}
|
||||
log.info("Scheduler shut down for applicationId: {}", applicationId);
|
||||
}
|
||||
|
||||
// Create a dedicated thread for asynchronous processing
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor(runnable -> {
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.setName("AsyncNdgProcessing-" + applicationId);
|
||||
return thread;
|
||||
});
|
||||
executorMap.put(applicationId, executor);
|
||||
|
||||
executor.submit(() -> {
|
||||
try {
|
||||
log.info("Starting async processing for applicationId: {}", applicationId);
|
||||
processNdgGeneration(applicationId);
|
||||
} catch (Exception e) {
|
||||
log.error("Error in async NDG processing for applicationId: {}", applicationId, e);
|
||||
} finally {
|
||||
// Cleanup resources
|
||||
ExecutorService executorToShutdown = executorMap.remove(applicationId);
|
||||
if (executorToShutdown != null) {
|
||||
executorToShutdown.shutdown();
|
||||
}
|
||||
log.info("Async processing completed for applicationId: {}", applicationId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void processNdgGeneration(Long applicationId) {
|
||||
private void processNdgGeneration(ApplicationEntity application, CompanyEntity company, HubEntity hub) {
|
||||
// Validate application, company, and hub
|
||||
Long applicationId = application.getId();
|
||||
log.info("Starting NDG generation process for applicationId: {}", applicationId);
|
||||
ApplicationEntity application = applicationService.validateApplication(applicationId);
|
||||
CompanyEntity company = companyService.validateCompany(application.getCompanyId());
|
||||
HubEntity hub = hubRepository.findByHubId(application.getHubId());
|
||||
|
||||
if (!hub.getUniqueUuid().equals(defaultHubUuid)) {
|
||||
log.info("Ndg cannot be created for another Hub, it is default for Gepafin.");
|
||||
@@ -484,103 +538,129 @@ public class AppointmentDao {
|
||||
String authorizationToken = getBearerToken(hub);
|
||||
|
||||
// Try retrieving NDG by VAT number
|
||||
AppointmentLoginResponse ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application);
|
||||
NdganagEntity ndganagEntity = ndganagRepository.findByVatNumber(company.getVatNumber());
|
||||
AppointmentLoginResponse ndgResponse=new AppointmentLoginResponse();
|
||||
if (ndganagEntity != null || ndganagEntity.getNdg() != null) {
|
||||
ndgResponse.setNdg(ndganagEntity.getNdg());
|
||||
}else {
|
||||
ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application);
|
||||
}
|
||||
if (isNdgValid(ndgResponse.getNdg())) {
|
||||
saveNdgAndIdVisura(application, company, ndgResponse.getNdg());
|
||||
saveNdg(application, company, ndgResponse.getNdg());
|
||||
log.info("NDG successfully generated for applicationId: {}", applicationId);
|
||||
} else {
|
||||
// If NDG isn't immediately available, start polling
|
||||
log.info("Polling for NDG for applicationId: {}", applicationId);
|
||||
handleNdgPolling(application, company, hub, authorizationToken);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred during NDG generation. ApplicationId: {}, CompanyId: {}, HubId: {}, Error: {}",
|
||||
applicationId, company.getId(), hub.getId(), e.getMessage(), e);
|
||||
log.error("Exception occurred during NDG generation. ApplicationId: {}, CompanyId: {}, HubId: {}, Error: {}", applicationId, company.getId(), hub.getId(),
|
||||
e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNdgPolling(ApplicationEntity application, CompanyEntity company, HubEntity hub, String authorizationToken) {
|
||||
|
||||
try {
|
||||
log.info("Starting NDG polling for applicationId: {}, CompanyId: {}, HubId: {}", application.getId(),company.getId(), hub.getId());
|
||||
log.info("Starting single‐shot NDG polling attempt for applicationId: {}, CompanyId: {}, HubId: {}", application.getId(), company.getId(), hub.getId());
|
||||
ApplicationEntity oldApplication = Utils.getClonedEntityForData(application);
|
||||
CompanyEntity oldCompanyEntity = Utils.getClonedEntityForData(company);
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
while (true) {
|
||||
if (application.getNdg() != null) {
|
||||
log.info("NDG retrieved for applicationId: {}", application.getId());
|
||||
break;
|
||||
}
|
||||
long twoHoursMs = TimeUnit.HOURS.toMillis(2);
|
||||
|
||||
try {
|
||||
// Fetch Ndg via creating visura
|
||||
AppointmentLoginResponse visuraResponse = createVisura(company, authorizationToken, hub);
|
||||
if (isNdgValid(visuraResponse.getNdg())) {
|
||||
log.info("Valid NDG retrieved from create visura api response: {} | ApplicationId: {}", visuraResponse.getNdg(), application.getId());
|
||||
company.setNdg(visuraResponse.getNdg());
|
||||
application.setNdg(visuraResponse.getNdg());
|
||||
application.setNdgStatus(GepafinConstant.NDG_GENERATED);
|
||||
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
|
||||
application.setIdVisura(visuraResponse.getIdVisura());
|
||||
applicationRepository.save(application);
|
||||
companyRepository.save(company);
|
||||
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(
|
||||
application.getApplicationEvaluationId());
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||
placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.NDG_GENERATION);
|
||||
notificationDao.sendNotificationToSuperUser(application, placeHolders, NotificationTypeEnum.NDG_GENERATION);
|
||||
log.info("Got NDG and saved successfully for applicationId: {}", application.getId());
|
||||
break;
|
||||
} else {
|
||||
// Fetch Visura list and attempt to parse NDG
|
||||
String visuraListJson = getVisuraList(visuraResponse.getIdVisura(), authorizationToken, application, hub);
|
||||
log.debug("Parsing NDG from visura list response | ApplicationId: {}", application.getId());
|
||||
String ndg = parseNdgFromVisuraListResponse(visuraListJson);
|
||||
if (isNdgValid(ndg)) {
|
||||
// CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company);
|
||||
// ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
|
||||
// 1) If NDG was already populated (perhaps by another thread), skip polling.
|
||||
if (application.getNdg() != null) {
|
||||
log.info("NDG already present for applicationId {}. Exiting single‐shot polling.", application.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Valid NDG retrieved: {} | ApplicationId: {}", ndg, application.getId());
|
||||
company.setNdg(ndg);
|
||||
application.setNdg(ndg);
|
||||
// 2) Attempt to create Visura (this may immediately return a valid NDG)
|
||||
AppointmentLoginResponse visuraResponse = createVisura(company, authorizationToken, hub);
|
||||
|
||||
// 2a) If createVisura gave us a valid NDG, persist & exit
|
||||
String fetchedNdg = visuraResponse.getNdg();
|
||||
if (isNdgValid(fetchedNdg)) {
|
||||
log.info("Valid NDG retrieved from createVisura(): {} | applicationId: {}", fetchedNdg, application.getId());
|
||||
|
||||
company.setNdg(fetchedNdg);
|
||||
application.setNdg(fetchedNdg);
|
||||
application.setNdgStatus(NdgStatusEnum.NDG_GENERATED.getValue());
|
||||
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
|
||||
application.setIdVisura(visuraResponse.getIdVisura());
|
||||
|
||||
companyRepository.save(company);
|
||||
applicationRepository.save(application);
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplication).newData(application).build());
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyEntity).newData(company).build());
|
||||
|
||||
ApplicationEvaluationEntity eval = applicationEvaluationService.validateApplicationEvaluation(application.getApplicationEvaluationId());
|
||||
Map<String, String> placeholders = new HashMap<>();
|
||||
placeholders.put("{{call_name}}", application.getCall().getName());
|
||||
placeholders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
notificationDao.sendNotificationToInstructor(placeholders, eval, NotificationTypeEnum.NDG_GENERATION);
|
||||
notificationDao.sendNotificationToSuperUser(application, placeholders, NotificationTypeEnum.NDG_GENERATION);
|
||||
|
||||
log.info("NDG saved successfully for applicationId: {}", application.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 2b) If no immediate NDG, fetch the Visura list JSON and parse out NDG
|
||||
String visuraListJson = getVisuraList(visuraResponse.getIdVisura(), authorizationToken, application, hub);
|
||||
log.debug("Parsing NDG from VisuraList JSON for applicationId: {}", application.getId());
|
||||
String parsedNdg = parseNdgFromVisuraListResponse(visuraListJson);
|
||||
|
||||
if (isNdgValid(parsedNdg)) {
|
||||
log.info("Valid NDG parsed from VisuraList: {} | applicationId: {}", parsedNdg, application.getId());
|
||||
|
||||
company.setNdg(parsedNdg);
|
||||
application.setNdg(parsedNdg);
|
||||
application.setNdgStatus(GepafinConstant.NDG_GENERATED);
|
||||
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
|
||||
application.setIdVisura(visuraResponse.getIdVisura());
|
||||
applicationRepository.save(application);
|
||||
|
||||
companyRepository.save(company);
|
||||
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(
|
||||
application.getApplicationEvaluationId());
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||
placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
notificationDao.sendNotificationToInstructor(placeHolders, applicationEvaluationEntity, NotificationTypeEnum.NDG_GENERATION);
|
||||
notificationDao.sendNotificationToSuperUser(application, placeHolders, NotificationTypeEnum.NDG_GENERATION);
|
||||
applicationRepository.save(application);
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplication).newData(application).build());
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyEntity).newData(company).build());
|
||||
|
||||
ApplicationEvaluationEntity eval = applicationEvaluationService.validateApplicationEvaluation(application.getApplicationEvaluationId());
|
||||
Map<String, String> placeholders = new HashMap<>();
|
||||
placeholders.put("{{call_name}}", application.getCall().getName());
|
||||
placeholders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
notificationDao.sendNotificationToInstructor(placeholders, eval, NotificationTypeEnum.NDG_GENERATION);
|
||||
notificationDao.sendNotificationToSuperUser(application, placeholders, NotificationTypeEnum.NDG_GENERATION);
|
||||
|
||||
log.info("NDG saved successfully for applicationId: {}", application.getId());
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Check if polling has timed out
|
||||
if (System.currentTimeMillis() - startTime > TimeUnit.HOURS.toMillis(2)) {
|
||||
log.warn("NDG polling timed out for applicationId: {}", application.getId());
|
||||
|
||||
// 3) Neither direct API nor parsing yielded a valid NDG. Check timeout.
|
||||
if (System.currentTimeMillis() - startTime > twoHoursMs) {
|
||||
log.warn("NDG polling timed out after 2 hours for applicationId: {}", application.getId());
|
||||
application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||
applicationRepository.save(application);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait before the next polling attempt
|
||||
Thread.sleep(TimeUnit.MINUTES.toMillis(15));
|
||||
} catch (InterruptedException e) {
|
||||
log.warn("NDG polling interrupted for applicationId: {}", application.getId());
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
// 4) No NDG yet—just return. The scheduler will retry in 15 minutes.
|
||||
log.info("No valid NDG yet for applicationId {}. Returning to scheduler—next attempt in 15 minutes.", application.getId());
|
||||
} catch (Exception e) {
|
||||
log.error("Error during NDG polling for applicationId: {}", application.getId(), e);
|
||||
log.error("Exception during NDG polling for applicationId: {}", application.getId(), e);
|
||||
// If timeout after exception, mark NDG_FAILED
|
||||
if (System.currentTimeMillis() - startTime > twoHoursMs) {
|
||||
log.warn("Example: exiting single‐shot polling due to timeout after exception for applicationId: {}", application.getId());
|
||||
application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||
applicationRepository.save(application);
|
||||
} else {
|
||||
log.info("Exception occurred but not timed out for applicationId {}. Returning to scheduler for next attempt in 15 minutes.", application.getId());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
||||
log.info("NDG polling completed for applicationId: {}", application.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private static String getBearerToken(HubEntity hub) {
|
||||
|
||||
@@ -592,14 +672,21 @@ public class AppointmentDao {
|
||||
return ndg != null && !ndg.isEmpty();
|
||||
}
|
||||
|
||||
private void saveNdgAndIdVisura(ApplicationEntity application, CompanyEntity company, String ndg) {
|
||||
private void saveNdg(ApplicationEntity application, CompanyEntity company, String ndg) {
|
||||
|
||||
ApplicationEntity oldApplication = Utils.getClonedEntityForData(application);
|
||||
CompanyEntity oldCompanyEntity = Utils.getClonedEntityForData(company);
|
||||
application.setNdg(ndg);
|
||||
application.setNdgStatus(GepafinConstant.NDG_GENERATED);
|
||||
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
|
||||
company.setNdg(ndg);
|
||||
companyRepository.save(company);
|
||||
applicationRepository.save(application);
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplication).newData(application).build());
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyEntity).newData(company).build());
|
||||
|
||||
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(application.getApplicationEvaluationId());
|
||||
// Map<String, String> placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.NDG_GENERATION);
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
@@ -638,10 +725,7 @@ public class AppointmentDao {
|
||||
try {
|
||||
log.info("Initiating NDG retrieval by VAT number | ApplicationId: {}, HubId: {}, VAT: {}", application.getId(), hub.getId(), vatNumber);
|
||||
// Prepare the NDG request
|
||||
AppointmentNdgRequest ndgRequest = getAppointmentNdgRequest(vatNumber);
|
||||
// Call the API to retrieve NDG
|
||||
ResponseEntity<Object> response = appointmentApiService.getNdgByVatNumber(ndgRequest, authorizationToken);
|
||||
String responseJson = Utils.convertObjectToJson(response.getBody());
|
||||
String responseJson = getNdgFromExternalService(vatNumber, authorizationToken);
|
||||
// Parse and return the NDG response
|
||||
return parseNdgResponse(responseJson);
|
||||
} catch (FeignException.Forbidden forbiddenException) {
|
||||
@@ -797,30 +881,38 @@ public class AppointmentDao {
|
||||
}
|
||||
|
||||
public AppointmentLoginResponse parseNdgResponse(String jsonResponse) {
|
||||
AppointmentLoginResponse loginResponse = new AppointmentLoginResponse();
|
||||
String ndg=extractNdg(jsonResponse);
|
||||
if (ndg==null){ return null;}
|
||||
else {
|
||||
loginResponse.setNdg(ndg);
|
||||
}
|
||||
return loginResponse;
|
||||
}
|
||||
|
||||
private String extractNdg(String jsonResponse) {
|
||||
try {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode rootNode = objectMapper.readTree(jsonResponse);
|
||||
JsonNode dataArray = rootNode.get(GepafinConstant.DATA_STRING);
|
||||
if (dataArray == null || !dataArray.isArray() || dataArray.isEmpty()) {
|
||||
log.info("NDG data is empty or missing in the response.");
|
||||
AppointmentLoginResponse emptyResponse = new AppointmentLoginResponse();
|
||||
emptyResponse.setNdg(null);
|
||||
return emptyResponse;
|
||||
return null;
|
||||
}
|
||||
JsonNode firstDataEntry = dataArray.get(0);
|
||||
AppointmentLoginResponse response = new AppointmentLoginResponse();
|
||||
if (firstDataEntry.has(GepafinConstant.NDG_STRING)) {
|
||||
response.setNdg(normalizeNullValue(firstDataEntry.get(GepafinConstant.NDG_STRING).asText()));
|
||||
String ndg=normalizeNullValue(firstDataEntry.get(GepafinConstant.NDG_STRING).asText());
|
||||
return ndg;
|
||||
}
|
||||
return response;
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to parse response: {}", e.getMessage(), e);
|
||||
throw new RuntimeException("Failed to parse NDG response.", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String normalizeNullValue(String value) {
|
||||
public String normalizeNullValue(String value) {
|
||||
|
||||
return (value == null || GepafinConstant.NULL_STRING.equalsIgnoreCase(value.trim())) ? null : value;
|
||||
}
|
||||
@@ -1235,4 +1327,156 @@ public class AppointmentDao {
|
||||
throw new RuntimeException("Failed to parse response: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void startAsyncNdgProcessing(Long applicationId) {
|
||||
if (executorMap.containsKey(applicationId)) {
|
||||
log.warn("Async processing already running for applicationId: {}", applicationId);
|
||||
return;
|
||||
}
|
||||
ApplicationEntity application = applicationService.validateApplication(applicationId);
|
||||
CompanyEntity company = companyService.validateCompany(application.getCompanyId());
|
||||
ApplicationEntity oldApplication = Utils.getClonedEntityForData(application);
|
||||
CompanyEntity oldCompanyEntity = Utils.getClonedEntityForData(company);
|
||||
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
|
||||
Thread t = new Thread(r);
|
||||
t.setName("AsyncNdgPolling-" + applicationId);
|
||||
return t;
|
||||
});
|
||||
|
||||
executorMap.put(applicationId, scheduler);
|
||||
application.setNdgStatus(NdgStatusEnum.NDG_IN_PROGRESS.getValue());
|
||||
applicationRepository.save(application);
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplication).newData(application).build());
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
long twoHoursMs = TimeUnit.HOURS.toMillis(2);
|
||||
long fifteenMin = 15;
|
||||
|
||||
HubEntity hub = hubRepository.findByHubId(application.getHubId());
|
||||
|
||||
// 1. Run full NDG generation logic once upfront
|
||||
processNdgGeneration(application, company, hub);
|
||||
|
||||
AtomicReference<ScheduledFuture<?>> futureRef = new AtomicReference<>();
|
||||
|
||||
// 2. Now define the polling logic ONLY
|
||||
Runnable pollingTask = () -> {
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes, true);
|
||||
Utils.setHttpServletRequestForThread(request, HttpMethodEnum.POST.getValue(),
|
||||
GepafinConstant.CREATE_NDG, (Long) request.getAttribute(GepafinConstant.USER_ACTION_ID));
|
||||
try {
|
||||
|
||||
// Stop if timeout
|
||||
if (System.currentTimeMillis() - startTime > twoHoursMs) {
|
||||
log.warn("Polling timed out for applicationId {}. Marking NDG_FAILED.", applicationId);
|
||||
application.setNdgStatus(GepafinConstant.NDG_FAILED);
|
||||
applicationRepository.save(application);
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplication).newData(application).build());
|
||||
|
||||
futureRef.get().cancel(false);
|
||||
shutdownScheduler(applicationId);
|
||||
return;
|
||||
}
|
||||
|
||||
// If NDG already present or marked failed
|
||||
if (isNdgValid(application.getNdg()) || GepafinConstant.NDG_FAILED.equals(application.getNdgStatus())) {
|
||||
log.info("NDG already present or failed for applicationId {}. Stopping polling.", applicationId);
|
||||
futureRef.get().cancel(false);
|
||||
shutdownScheduler(applicationId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only Visura polling here:
|
||||
String visuraListJson = getVisuraList(application.getIdVisura(), hub.getAppointmentAuthTokenId(), application, hub);
|
||||
String parsedNdg = parseNdgFromVisuraListResponse(visuraListJson);
|
||||
|
||||
if (isNdgValid(parsedNdg)) {
|
||||
log.info("Valid NDG parsed from VisuraList: {} | applicationId: {}", parsedNdg, application.getId());
|
||||
|
||||
company.setNdg(parsedNdg);
|
||||
application.setNdg(parsedNdg);
|
||||
application.setNdgStatus(GepafinConstant.NDG_GENERATED);
|
||||
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
|
||||
// application.setIdVisura(visuraResponse.getIdVisura());
|
||||
|
||||
companyRepository.save(company);
|
||||
applicationRepository.save(application);
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplication).newData(application).build());
|
||||
loggingUtil.addVersionHistory(
|
||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyEntity).newData(company).build());
|
||||
|
||||
ApplicationEvaluationEntity eval = applicationEvaluationService.validateApplicationEvaluation(application.getApplicationEvaluationId());
|
||||
Map<String, String> placeholders = new HashMap<>();
|
||||
placeholders.put("{{call_name}}", application.getCall().getName());
|
||||
placeholders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
notificationDao.sendNotificationToInstructor(placeholders, eval, NotificationTypeEnum.NDG_GENERATION);
|
||||
notificationDao.sendNotificationToSuperUser(application, placeholders, NotificationTypeEnum.NDG_GENERATION);
|
||||
|
||||
log.info("NDG saved successfully for applicationId: {}", application.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
log.error("Error during NDG polling: {}", ex.getMessage(), ex);
|
||||
}
|
||||
};
|
||||
|
||||
ScheduledFuture<?> future = scheduler.scheduleWithFixedDelay(pollingTask, fifteenMin, fifteenMin, TimeUnit.MINUTES);
|
||||
futureRef.set(future);
|
||||
}
|
||||
|
||||
public NdgResponse getNdgByVatNumber(String vatNumber, UserEntity userEntity) {
|
||||
HubEntity hub=userEntity.getHub();
|
||||
NdganagEntity ndganagEntity = ndganagRepository.findByVatNumber(vatNumber);
|
||||
NdgResponse ndgResponse=new NdgResponse();
|
||||
String jsonResponse=null;
|
||||
String authorizationToken = hub.getAppointmentAuthTokenId();
|
||||
if (ndganagEntity == null || ndganagEntity.getNdg() == null) {
|
||||
|
||||
try {
|
||||
log.info("Initiating NDG retrieval by VAT number | HubId: {}, VAT: {}", hub.getId(), vatNumber);
|
||||
// Prepare the NDG request
|
||||
jsonResponse=getNdgFromExternalService(vatNumber, authorizationToken);
|
||||
checkAndSaveNdg(jsonResponse, ndgResponse);
|
||||
// Parse and return the NDG response
|
||||
} catch (FeignException.Forbidden forbiddenException) {
|
||||
log.error("403 Forbidden during NDG retrieval | HubId: {}", hub.getId());
|
||||
logForbiddenError();
|
||||
// Regenerate the token and retry
|
||||
String newAuthorizationToken = regenerateTokenAndSave(hub, null);
|
||||
jsonResponse= getNdgFromExternalService(vatNumber,newAuthorizationToken);
|
||||
if (checkAndSaveNdg(jsonResponse, ndgResponse)) return null;
|
||||
} catch (Exception e) {
|
||||
log.error("Error during NDG retrieval |, HubId: {}, Message: {}", hub.getId(), e.getMessage(), e);
|
||||
throw new RuntimeException("NDG retrieval failed.", e);
|
||||
}
|
||||
}else {
|
||||
ndgResponse.setNdg(ndganagEntity.getNdg());
|
||||
}
|
||||
return ndgResponse;
|
||||
}
|
||||
|
||||
private boolean checkAndSaveNdg(String jsonResponse, NdgResponse ndgResponse) {
|
||||
String ndg=extractNdg(jsonResponse);
|
||||
if (ndg==null){
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
ndgResponse.setNdg(ndg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getNdgFromExternalService(String vatNumber, String authorizationToken) {
|
||||
AppointmentNdgRequest ndgRequest = getAppointmentNdgRequest(vatNumber);
|
||||
// Call the API to retrieve NDG
|
||||
ResponseEntity<Object> response = appointmentApiService.getNdgByVatNumber(ndgRequest, authorizationToken);
|
||||
String responseJson = Utils.convertObjectToJson(response.getBody());
|
||||
return responseJson;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.gepafin.tendermanagement.dao;
|
||||
|
||||
import org.springframework.data.domain.Pageable; // Correct package
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -531,7 +532,11 @@ public class CompanyDao {
|
||||
Map<String, Object> dataMap = Utils.extractMap(companyDataMap, "data");
|
||||
Object dataObj = companyDataMap.get("data");
|
||||
|
||||
if (dataMap == null) {
|
||||
if (dataObj instanceof Map<?, ?> singleMap) {
|
||||
dataMap = (Map<String, Object>) singleMap;
|
||||
} else if (dataObj instanceof List<?> list && !list.isEmpty() && list.get(0) instanceof Map<?, ?> firstMap) {
|
||||
dataMap = (Map<String, Object>) firstMap;
|
||||
} else {
|
||||
log.warn("Company ID {}: 'data' section is missing or invalid in the JSON.", company.getId());
|
||||
return;
|
||||
}
|
||||
@@ -540,11 +545,11 @@ public class CompanyDao {
|
||||
updateCodiceAtecoField(company);
|
||||
} else {
|
||||
|
||||
Object pecEmail = Utils.extractMap(dataMap, "pec");
|
||||
Object pecEmail = dataMap.get("pec");
|
||||
if (pecEmail == null) {
|
||||
log.warn("Company ID {}: 'pec' section is missing or invalid.", company.getId());
|
||||
company.setPec((String) pecEmail);
|
||||
}
|
||||
company.setPec((String) pecEmail);
|
||||
|
||||
// Extract 'atecoClassification' section
|
||||
Map<String, Object> atecoClassificationMap = Utils.extractMap(dataMap, "atecoClassification");
|
||||
@@ -577,49 +582,79 @@ public class CompanyDao {
|
||||
}
|
||||
|
||||
public void getCompanyEntity() {
|
||||
List<CompanyEntity> companyEntities=companyRepository.findAll();
|
||||
List<CompanyEntity> companyEntities=companyRepository.findByJsonIsNotNullAndPecIsNull();
|
||||
List<CompanyEntity> companyEntityList=new ArrayList<>();
|
||||
for (CompanyEntity company:companyEntities){
|
||||
if(company.getJson()!=null){
|
||||
if(company.getJson()!=null && company.getPec()==null){
|
||||
if (company == null || company.getJson() == null || company.getJson().isEmpty()) {
|
||||
log.warn("Company is null or JSON data is empty.");
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> vatCheckResponse = Utils.convertJsonStringToMap(company.getJson());
|
||||
|
||||
if (vatCheckResponse == null) {
|
||||
log.warn("Company ID {}: Invalid JSON response.", company.getId());
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> companyDataMap = Utils.convertJsonStringToMap(company.getJson());
|
||||
if (companyDataMap == null) {
|
||||
log.warn("Company ID {}: Failed to parse JSON data.", company.getId());
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Object dataObj = vatCheckResponse.get("data");
|
||||
if (!(dataObj instanceof Map<?, ?> dataMap)) {
|
||||
log.warn("Company ID {}: 'data' is missing or not a valid object.", company.getId());
|
||||
return;
|
||||
Map<String, Object> dataMap=null;
|
||||
// if (!(dataObj instanceof Map<?, ?> dataMap)) {
|
||||
// log.warn("Company ID {}: 'data' is missing or not a valid object.", company.getId());
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (dataObj instanceof Map<?, ?> singleMap) {
|
||||
dataMap = (Map<String, Object>) singleMap;
|
||||
} else if (dataObj instanceof List<?> list && !list.isEmpty() && list.get(0) instanceof Map<?, ?> firstMap) {
|
||||
dataMap = (Map<String, Object>) firstMap;
|
||||
} else {
|
||||
log.warn("Company ID {}: 'data' section is missing or invalid in the JSON.", company.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (dataMap.containsKey("pec")) {
|
||||
Object pecEmailObj = dataMap.get("pec");
|
||||
if (pecEmailObj instanceof String pec && !pec.isEmpty()) {
|
||||
company.setPec(pec); // Only set if valid string
|
||||
companyEntityList.add(company);
|
||||
} else {
|
||||
log.warn("Company ID {}: 'pec' is missing, empty, or not a string.", company.getId());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!dataMap.containsKey("dettaglio")) {
|
||||
log.warn("Company ID {}: 'dettaglio' not present inside 'data'. Skipping codiceAteco update.", company.getId());
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Object dettaglioObj = dataMap.get("dettaglio");
|
||||
if (!(dettaglioObj instanceof Map<?, ?> dettaglio)) {
|
||||
log.warn("Company ID {}: 'dettaglio' is not a valid object.", company.getId());
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
Object pecEmailObj = dettaglio.get("pec");
|
||||
if (pecEmailObj instanceof String pec && !pec.isEmpty()) {
|
||||
if(pec!=null) {
|
||||
company.setPec(pec); // Only set if valid string
|
||||
companyEntityList.add(company);
|
||||
}
|
||||
} else {
|
||||
log.warn("Company ID {}: 'pec' is missing, empty, or not a string.", company.getId());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
companyRepository.saveAll(companyEntityList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,8 +174,16 @@ public class EmailNotificationDao {
|
||||
public Map<String, String> prepareEmailPlaceholders(ApplicationEntity applicationEntity, ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity){
|
||||
Map<String, String> bodyPlaceholders = new HashMap<>();
|
||||
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", applicationEntity.getProtocol().getProtocolNumber().toString());
|
||||
bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY));
|
||||
String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber());
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocolNumber);
|
||||
String protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY);
|
||||
if(applicationEntity.getProtocol().getExternalProtocolDate()!=null){
|
||||
protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY);
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_date}}", protocolDate);
|
||||
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
|
||||
bodyPlaceholders.put("{{response_days}}", applicationAmendmentRequestEntity.getResponseDays().toString());
|
||||
|
||||
@@ -259,8 +267,16 @@ public class EmailNotificationDao {
|
||||
public void sendAdmissibilityNotificationEmailForAdmissibleApplication(ApplicationEntity applicationEntity) {
|
||||
Map<String, String> bodyPlaceholders = new HashMap<>();
|
||||
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", applicationEntity.getProtocol().getProtocolNumber().toString());
|
||||
bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatCreatedDate(applicationEntity.getProtocol().getCreatedDate()));
|
||||
String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber());
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocolNumber);
|
||||
String protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY);
|
||||
if(applicationEntity.getProtocol().getExternalProtocolDate()!=null){
|
||||
protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY);
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_date}}", protocolDate);
|
||||
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
|
||||
|
||||
sendEmail(applicationEntity, SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum.ADMISSIBILITY_NOTIFICATION, bodyPlaceholders, null,null);
|
||||
@@ -269,8 +285,16 @@ public class EmailNotificationDao {
|
||||
public void sendInadmissibilityEmailForRejectedApplication(ApplicationEntity applicationEntity,ApplicationEvaluationEntity applicationEvaluationEntity) {
|
||||
Map<String, String> bodyPlaceholders = new HashMap<>();
|
||||
bodyPlaceholders.put("{{call_name}}", applicationEntity.getCall().getName());
|
||||
bodyPlaceholders.put("{{protocol_number}}", applicationEntity.getProtocol().getProtocolNumber().toString());
|
||||
bodyPlaceholders.put("{{protocol_date}}", DateTimeUtil.formatCreatedDate(applicationEntity.getProtocol().getCreatedDate()));
|
||||
String protocolNumber=applicationEntity.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(applicationEntity.getProtocol().getProtocolNumber());
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_number}}", protocolNumber);
|
||||
String protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getCreatedDate(), GepafinConstant.DD_MM_YYYY);
|
||||
if(applicationEntity.getProtocol().getExternalProtocolDate()!=null){
|
||||
protocolDate= DateTimeUtil.formatLocalDateTime(applicationEntity.getProtocol().getExternalProtocolDate(), GepafinConstant.DD_MM_YYYY);
|
||||
}
|
||||
bodyPlaceholders.put("{{protocol_date}}", protocolDate);
|
||||
bodyPlaceholders.put("{{protocol_time}}", DateTimeUtil.parseLocalTimeToString(applicationEntity.getProtocol().getTime(), GepafinConstant.HH_MM_SS));
|
||||
bodyPlaceholders.put("{{form_text}}", applicationEvaluationEntity.getMotivation());
|
||||
|
||||
|
||||
@@ -174,7 +174,11 @@ public class NotificationDao {
|
||||
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||
placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
String protocolNumber=application.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(application.getProtocol().getProtocolNumber());
|
||||
}
|
||||
placeHolders.put("{{protocol_number}}", protocolNumber);
|
||||
NotificationReq notificationReq = createNotificationReq(notificationTypeEnum.getValue(), placeHolders, application.getUserId(), application.getUserWithCompany(),
|
||||
listOf(application.getCompanyId()));
|
||||
sendNotification(notificationReq);
|
||||
|
||||
@@ -181,15 +181,15 @@ public class ProtocolDao {
|
||||
|
||||
Map<String, Object> 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);
|
||||
requestBody.put(GepafinConstant.PROTOCOL_COMPANY_NAME_VAT_NUMBER,company.getCompanyName());
|
||||
Map<String, Object> 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_TIPO_CORRISPONDENTE, mittenteValue);
|
||||
mittente.put(GepafinConstant.PROTOCOL_MEZZO,mezzo);
|
||||
mittente.put(GepafinConstant.PROTOCOL_INDIRIZZO_PEC,pecEmail);
|
||||
mittente.put(GepafinConstant.PROTOCOL_COMPANY_VAT_NUMBER,vatNumber);
|
||||
mittente.put(GepafinConstant.PROTOCOL_COMPANY_NAME,company.getCompanyName());
|
||||
List<Map<String,Object>> destinatariObject=new ArrayList<>();
|
||||
Map<String, Object> destinatari = new HashMap<>();
|
||||
destinatari.put(GepafinConstant.PROTOCOL_CODICE_UO,codiceUo);
|
||||
|
||||
@@ -73,4 +73,7 @@ public class ApplicationEntity extends BaseEntity {
|
||||
@Column(name = "APPLICATION_EVALUATION_ID")
|
||||
private Long applicationEvaluationId;
|
||||
|
||||
@Column(name = "PEC_EMAIL")
|
||||
private String pecEmail;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package net.gepafin.tendermanagement.entities;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Data;
|
||||
import org.hibernate.annotations.Where;
|
||||
|
||||
@Entity
|
||||
@Table(name = "NDGANAG")
|
||||
@Data
|
||||
@Where(clause = "is_deleted = false")
|
||||
public class NdganagEntity extends BaseEntity{
|
||||
|
||||
@Column(name = "NDG")
|
||||
private String ndg;
|
||||
|
||||
@Column(name = "COMPANY_NAME")
|
||||
private String companyName;
|
||||
|
||||
@Column(name = "VAT_NUMBER")
|
||||
private String vatNumber;
|
||||
|
||||
@Column(name = "CODICE_FISCALE")
|
||||
private String codiceFiscale;
|
||||
|
||||
@Column(name = "JSON")
|
||||
private String json;
|
||||
|
||||
@Column(name = "IS_DELETED")
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package net.gepafin.tendermanagement.enums;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum HttpMethodEnum {
|
||||
POST("POST"), PUT("PUT"), GET("GET"), DELETE("DELETE");
|
||||
|
||||
private String value;
|
||||
|
||||
HttpMethodEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.gepafin.tendermanagement.enums;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum NdgStatusEnum {
|
||||
|
||||
NDG_INITITATED("NDG_INITITATED"),
|
||||
NDG_GENERATED("NDG_GENERATED"),
|
||||
NDG_IN_PROGRESS("NDG_IN_PROGRESS");
|
||||
|
||||
private String value;
|
||||
|
||||
NdgStatusEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@ public enum UserActionContextEnum {
|
||||
GET_COMPANY_BY_USER("GET_COMPANY_BY_USER"),
|
||||
REMOVE_COMPANY_FROM_USER("REMOVE_COMPANY_FROM_USER"),
|
||||
UPDATE_COMPANY_JSON("UPDATE_COMPANY_JSON"),
|
||||
EXTRACT_PEC_FROM_COMPANY("EXTRACT_PEC_FROM_COMPANY"),
|
||||
|
||||
/** LookUpData action context **/
|
||||
CREATE_LOOKUP_DATA("CREATE_LOOKUP_DATA"),
|
||||
@@ -180,6 +181,7 @@ public enum UserActionContextEnum {
|
||||
CHECK_OR_CREATE_NDG_CODE("CHECK_OR_CREATE_NDG_CODE"),
|
||||
CREATE_APPOINTMENT("CREATE_APPOINTMENT"),
|
||||
UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM("UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM"),
|
||||
GET_NDG_BY_VAT_NUMBER("GET_NDG_BY_VAT_NUMBER"),
|
||||
|
||||
GET_ALL_NOTIFICATION_BY_PAGINATION("GET_ALL_NOTIFICATION_BY_PAGINATION"),
|
||||
GET_ALL_CALL_BY_PAGINATION("GET_ALL_CALL_BY_PAGINATION"),
|
||||
|
||||
@@ -31,5 +31,7 @@ public interface CompanyRepository extends JpaRepository<CompanyEntity, Long> {
|
||||
""")
|
||||
Page<CompanyEntity> findCompaniesWithMissingVatCheck(Pageable pageable);
|
||||
|
||||
List<CompanyEntity> findByJsonIsNotNullAndPecIsNull();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package net.gepafin.tendermanagement.repositories;
|
||||
|
||||
import net.gepafin.tendermanagement.entities.NdganagEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
@Repository
|
||||
public interface NdganagRepository extends JpaRepository<NdganagEntity,Long> {
|
||||
|
||||
NdganagEntity findByVatNumber(String vatNumber);
|
||||
|
||||
|
||||
}
|
||||
@@ -91,7 +91,11 @@ public class ApplicationEvaluationScheduler {
|
||||
// Map<String, String> placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.EVALUATION_EXPIRED);
|
||||
Map<String, String> placeHolders = new HashMap<>();
|
||||
placeHolders.put("{{call_name}}", application.getCall().getName());
|
||||
placeHolders.put("{{protocol_number}}", String.valueOf(application.getProtocol().getProtocolNumber()));
|
||||
String protocolNumber=application.getProtocol().getExternalProtocolNumber();
|
||||
if(protocolNumber==null){
|
||||
protocolNumber= String.valueOf(application.getProtocol().getProtocolNumber());
|
||||
}
|
||||
placeHolders.put("{{protocol_number}}", protocolNumber);
|
||||
notificationDao.sendNotificationToSuperUser(application,placeHolders,NotificationTypeEnum.EVALUATION_EXPIRED);
|
||||
notificationDao.sendNotificationToInstructor(placeHolders,evaluation,NotificationTypeEnum.EVALUATION_EXPIRED);
|
||||
notificationDao.sendNotificationToInstructorManager(placeHolders,evaluation,NotificationTypeEnum.EVALUATION_EXPIRED);
|
||||
|
||||
@@ -13,4 +13,7 @@ public interface AppointmentService {
|
||||
AppointmentCreationResponse createAppointmentForApplication(HttpServletRequest request, Long applicationId, CreateAppointmentRequest createAppointmentRequest);
|
||||
|
||||
DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest);
|
||||
|
||||
NdgResponse getNdgByVatNumber(HttpServletRequest request,String vatNumber);
|
||||
|
||||
}
|
||||
|
||||
@@ -47,4 +47,5 @@ public interface CompanyService {
|
||||
|
||||
void updateMissingVatCheckResponses(HttpServletRequest request, LimitRequest limitRequest);
|
||||
|
||||
void extractPecFromJson(HttpServletRequest request);
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package net.gepafin.tendermanagement.service.impl;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import net.gepafin.tendermanagement.dao.AppointmentDao;
|
||||
import net.gepafin.tendermanagement.entities.UserEntity;
|
||||
import net.gepafin.tendermanagement.model.request.CreateAppointmentRequest;
|
||||
import net.gepafin.tendermanagement.model.request.UploadDocToExternalSystemRequest;
|
||||
import net.gepafin.tendermanagement.model.response.AppointmentCreationResponse;
|
||||
import net.gepafin.tendermanagement.model.response.DocumentUploadResponse;
|
||||
import net.gepafin.tendermanagement.model.response.NdgResponse;
|
||||
import net.gepafin.tendermanagement.service.AppointmentService;
|
||||
import net.gepafin.tendermanagement.util.Validator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -17,6 +19,9 @@ public class AppointmentServiceImpl implements AppointmentService {
|
||||
@Autowired
|
||||
private AppointmentDao appointmentDao;
|
||||
|
||||
@Autowired
|
||||
private Validator validator;
|
||||
|
||||
@Override
|
||||
public NdgResponse checkNdgForAppointment(HttpServletRequest request, Long applicationId) {
|
||||
|
||||
@@ -34,4 +39,11 @@ public class AppointmentServiceImpl implements AppointmentService {
|
||||
|
||||
return appointmentDao.uploadDocumentToExternalSystem(documentId, docToExternalSystemRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NdgResponse getNdgByVatNumber(HttpServletRequest request,String vatNumber) {
|
||||
UserEntity userEntity = validator.validateUser(request);
|
||||
NdgResponse ndgResponse= appointmentDao.getNdgByVatNumber(vatNumber,userEntity);
|
||||
return ndgResponse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,12 @@ public class CompanyServiceImpl implements CompanyService {
|
||||
@Override
|
||||
public void updateMissingVatCheckResponses(HttpServletRequest request, LimitRequest limitRequest) {
|
||||
UserEntity userEntity =validator.validateUser(request);
|
||||
companyDao.updateMissingVatCheckResponses(request, limitRequest);
|
||||
companyDao.updateMissingVatCheckResponses(request,limitRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extractPecFromJson(HttpServletRequest request) {
|
||||
UserEntity userEntity =validator.validateUser(request);
|
||||
companyDao.getCompanyEntity();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1052,5 +1052,17 @@ public class Utils {
|
||||
headers.add(org.apache.http.HttpHeaders.USER_AGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0");
|
||||
return headers;
|
||||
}
|
||||
|
||||
public static void setHttpServletRequestForThread(HttpServletRequest request,String methodType, String remoteUser, Long userActionId) {
|
||||
MockHttpServletRequest mockRequest = new MockHttpServletRequest();
|
||||
mockRequest.setRequestURI(request.getRequestURI());
|
||||
mockRequest.setMethod(methodType);
|
||||
mockRequest.setRemoteUser(remoteUser); // or pass it in if needed
|
||||
mockRequest.setAttribute(GepafinConstant.USER_ACTION_ID, userActionId);
|
||||
|
||||
ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest);
|
||||
RequestContextHolder.setRequestAttributes(attributes, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -56,4 +56,15 @@ public interface AppointmentApi {
|
||||
ResponseEntity<Response<DocumentUploadResponse>> uploadDocumentToExternalSystem(HttpServletRequest request,
|
||||
@Parameter(description = "The document id", required = true) @PathVariable(value = "documentId", required = true) Long documentId,
|
||||
@RequestBody UploadDocToExternalSystemRequest docToExternalSystemRequest);
|
||||
|
||||
@Operation(summary = "API to get ndg by vatNumber", responses = { @ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
|
||||
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
|
||||
@GetMapping(value = "/vatNumber/{vatNumber}", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
ResponseEntity<Response<NdgResponse>> getNdgByVatNumber(HttpServletRequest request,@PathVariable(value = "vatNumber", required = true) @Parameter(description = "vatNumber",required = true)String vatNumber);
|
||||
|
||||
}
|
||||
|
||||
@@ -169,4 +169,17 @@ public interface CompanyApi {
|
||||
@PreAuthorize("hasRole('ROLE_SUPER_ADMIN') ")
|
||||
ResponseEntity<Response<Void>> updateMissingVatCheckResponses(HttpServletRequest request,
|
||||
@Parameter(description = "Limit request object ", required = true) @RequestBody LimitRequest limitRequest);
|
||||
|
||||
@Operation(summary = "Api to extract pec from the company json", responses = { @ApiResponse(responseCode = "200", description = "OK"),
|
||||
@ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.NOTFOUND_ERROR_EXAMPLE) })),
|
||||
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
|
||||
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
|
||||
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
|
||||
@GetMapping(value = "/pec", produces = { "application/json" })
|
||||
@PreAuthorize("hasRole('ROLE_SUPER_ADMIN') ")
|
||||
ResponseEntity<Response<Void>> extractPecFromJson(HttpServletRequest request);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import net.gepafin.tendermanagement.service.AppointmentService;
|
||||
import net.gepafin.tendermanagement.util.LoggingUtil;
|
||||
import net.gepafin.tendermanagement.web.rest.api.AppointmentApi;
|
||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||
import org.opensaml.xmlsec.signature.G;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -81,4 +82,19 @@ public class AppointmentController implements AppointmentApi {
|
||||
.body(new Response<>(documentUploadResponse, Status.SUCCESS, Translator.toLocale(message)));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<NdgResponse>> getNdgByVatNumber(HttpServletRequest request,String vatNumber) {
|
||||
loggingUtil.logUserAction(
|
||||
UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPLOAD).actionContext(UserActionContextEnum.GET_NDG_BY_VAT_NUMBER).build());
|
||||
|
||||
NdgResponse ndgResponse= appointmentService.getNdgByVatNumber(request,vatNumber);
|
||||
if(ndgResponse==null){
|
||||
return ResponseEntity.status(HttpStatus.CREATED)
|
||||
.body(new Response<>(ndgResponse, Status.NOT_FOUND, Translator.toLocale(GepafinConstant.NDG_NOT_FOUND)));
|
||||
}
|
||||
|
||||
return ResponseEntity.status(HttpStatus.CREATED)
|
||||
.body(new Response<>(ndgResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_FETCH_SUCCESSFULLY)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,4 +201,17 @@ public class CompanyApiController implements CompanyApi{
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_UPDATED_SUCCESS_MSG)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Response<Void>> extractPecFromJson(HttpServletRequest request) {
|
||||
|
||||
log.info("Api to set pec from json field");
|
||||
|
||||
companyService.extractPecFromJson(request);
|
||||
|
||||
loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE).actionContext(UserActionContextEnum.EXTRACT_PEC_FROM_COMPANY).build());
|
||||
|
||||
return ResponseEntity.status(HttpStatus.OK)
|
||||
.body(new Response<>(null, Status.SUCCESS, Translator.toLocale(GepafinConstant.COMPANY_UPDATED_SUCCESS_MSG)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2960,4 +2960,24 @@
|
||||
path="db/dump/updated_form_field_05_06_2025.sql"/>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="06-06-2025_RK_180524" author="Rajesh Khore">
|
||||
<createTable tableName="ndganag">
|
||||
<column name="id" type="INTEGER" autoIncrement="true">
|
||||
<constraints primaryKey="true" primaryKeyName="ndganag_pkey" nullable="false"/>
|
||||
</column>
|
||||
<column name="ndg" type="VARCHAR(255)" />
|
||||
<column name="company_name" type="VARCHAR(255)"/>
|
||||
<column name="vat_number" type="VARCHAR(255)" />
|
||||
<column name="codice_fiscale" type="VARCHAR(255)" />
|
||||
<column name="json" type="TEXT"/>
|
||||
<column name="is_deleted" type="BOOLEAN"/>
|
||||
<column name="created_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
<column name="updated_date" type="TIMESTAMP WITHOUT TIME ZONE"/>
|
||||
</createTable>
|
||||
|
||||
<addColumn tableName="application">
|
||||
<column name="pec_email" type="VARCHAR(255)"></column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
||||
@@ -408,3 +408,5 @@ resend.email.sent.failed.msg = Failed to resend the email.
|
||||
application.readmit.success=Application has been readmitted successfully.
|
||||
no.email.log.msg = No failed emails found for given userActionId.
|
||||
user.action.id.not.found = User Action id not found.
|
||||
ndg.not.found=NDG not found.
|
||||
email.pec.cannot.null=Email pec is required.
|
||||
|
||||
@@ -399,3 +399,5 @@ resend.email.sent.failed.msg = Impossibile inviare nuovamente l'e-mail.
|
||||
application.readmit.success=L'applicazione è stata riammessa con successo.
|
||||
no.email.log.msg = Nessuna email trovata per userActionId specificato.
|
||||
user.action.id.not.found = ID azione utente non trovato.
|
||||
ndg.not.found=NDG non trovato.
|
||||
email.pec.cannot.null=L'indirizzo email pec è obbligatorio.
|
||||
|
||||
Reference in New Issue
Block a user