Resolved conficts

This commit is contained in:
rajesh
2024-12-12 14:54:57 +05:30
24 changed files with 453 additions and 240 deletions

View File

@@ -339,5 +339,8 @@ public class GepafinConstant {
public static final String HMAC_ALGO = "HmacSHA256"; public static final String HMAC_ALGO = "HmacSHA256";
public static final String ERROR_IN_GENERATING_NDG_TRY_AGAIN = "error.try.again"; public static final String ERROR_IN_GENERATING_NDG_TRY_AGAIN = "error.try.again";
public static final String POLLING_THREAD_NAME = "Ndg-Polling-Thread-"; public static final String POLLING_THREAD_NAME = "Ndg-Polling-Thread-";
public static final String DOCUMENT_UPLOADING_IN_PROGRESS = "document.uploading.is.in.progress";
public static final String ASYNC_DOCUMENT_UPLOAD_NAME = "AsyncDocumentUpload-";
public static final String All_DOCUMENT_CHECKED_AND_ONE_CHECKLIST_CHECKED="all.document.checked.and.one.checklist.checked";
} }

View File

@@ -105,12 +105,33 @@ public class ApplicationAmendmentRequestDao {
@Autowired @Autowired
private AssignedApplicationsDao assignedApplicationsDao; private AssignedApplicationsDao assignedApplicationsDao;
@Autowired
private ApplicationEvaluationDao applicationEvaluationDao;
public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) {
log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId);
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId);
Long applicationId = applicationEvaluationEntity.getApplicationId(); Long applicationId = applicationEvaluationEntity.getApplicationId();
ApplicationEntity application = applicationService.validateApplication(applicationId); List<FieldRequest> evaluationFileRequests=new ArrayList<>();
List<ChecklistRequest> checklistRequests=new ArrayList<>();
ApplicationEntity application = applicationService.validateApplication(applicationId);
String file=applicationEvaluationEntity.getFile();
String checkList=applicationEvaluationEntity.getChecklist();
if(file != null){
evaluationFileRequests=Utils.convertJsonStringToList(file,FieldRequest.class);
}
Boolean allValid = evaluationFileRequests.stream()
.anyMatch(fieldRequest -> fieldRequest.getValid() == null);
if(checkList != null) {
checklistRequests=Utils.convertJsonStringToList(checkList,ChecklistRequest.class);
}
boolean resultCheckList = checklistRequests.stream()
.anyMatch(checklistRequest -> Boolean.TRUE.equals(checklistRequest.getValid())) ? false : true;
if(Boolean.TRUE.equals(allValid) || Boolean.TRUE.equals(resultCheckList)){
throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.All_DOCUMENT_CHECKED_AND_ONE_CHECKLIST_CHECKED));
}
// Set common application-level details // Set common application-level details
String callName = application.getCall().getName(); String callName = application.getCall().getName();
Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null)
@@ -135,11 +156,18 @@ public class ApplicationAmendmentRequestDao {
List<ApplicationFormEntity> forms = applicationFormRepository.findByApplicationId(applicationId); List<ApplicationFormEntity> forms = applicationFormRepository.findByApplicationId(applicationId);
List<AmendmentFormFieldResponse> allFormFields = new ArrayList<>(); List<AmendmentFormFieldResponse> allFormFields = new ArrayList<>();
Map<String, FieldRequest> fieldRequestMap = evaluationFileRequests.stream()
.collect(Collectors.toMap(FieldRequest::getId, fieldRequest -> fieldRequest));
for (ApplicationFormEntity form : forms) { for (ApplicationFormEntity form : forms) {
String content = form.getForm().getContent(); String content = form.getForm().getContent();
List<Map<String, Object>> result = filterByName(content, "fileupload"); List<Map<String, Object>> result = filterByName(content, "fileupload");
allFormFields.addAll(getIdAndLabelFromResult(result)); List<AmendmentFormFieldResponse> amendmentFormFieldResponses= getIdAndLabelFromResult(result);
amendmentFormFieldResponses.removeIf(amendmentFormFieldResponse -> {
FieldRequest matchingRequest = fieldRequestMap.get(amendmentFormFieldResponse.getFieldId());
// Remove if no matching FieldRequest exists or if valid is true
return matchingRequest == null || Boolean.TRUE.equals(matchingRequest.getValid());
});
allFormFields.addAll(amendmentFormFieldResponses);
} }
response.setFormFields(allFormFields); response.setFormFields(allFormFields);
@@ -243,6 +271,9 @@ public class ApplicationAmendmentRequestDao {
String formFieldsJson = Utils.convertObjectToJson(formFieldRequestBean); String formFieldsJson = Utils.convertObjectToJson(formFieldRequestBean);
applicationAmendmentRequestEntity.setFormFields(formFieldsJson); applicationAmendmentRequestEntity.setFormFields(formFieldsJson);
} }
if(Boolean.FALSE.equals(applicationAmendmentRequest.getAmendmentDocument().isEmpty())) {
setAmendmentDocuments(applicationAmendmentRequest.getAmendmentDocument(), applicationAmendmentRequestEntity);
}
List<ApplicationAmendmentRequestEntity> amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId()); List<ApplicationAmendmentRequestEntity> amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId());
// Ensure startDate and initialDays are not null to avoid NullPointerException // Ensure startDate and initialDays are not null to avoid NullPointerException
if (amendmentRequest !=null && amendmentRequest.isEmpty() && applicationEvaluationEntity.getStartDate() != null && applicationEvaluationEntity.getInitialDays() != null ) { if (amendmentRequest !=null && amendmentRequest.isEmpty() && applicationEvaluationEntity.getStartDate() != null && applicationEvaluationEntity.getInitialDays() != null ) {
@@ -261,7 +292,7 @@ public class ApplicationAmendmentRequestDao {
Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub());
ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(
applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber, applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber,
userEntity.getHub().getId()); userEntity.getHub().getId(),false);
applicationAmendmentRequestEntity.setProtocol(protocolEntity); applicationAmendmentRequestEntity.setProtocol(protocolEntity);
ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT);
String evaluationStatusType = applicationEvaluationEntity.getStatus(); String evaluationStatusType = applicationEvaluationEntity.getStatus();
@@ -302,6 +333,16 @@ public class ApplicationAmendmentRequestDao {
return applicationAmendment; return applicationAmendment;
} }
private void setAmendmentDocuments(List<AmendmentFieldRequest> amendmentFieldRequest, ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity) {
amendmentFieldRequest.stream().forEach(amendmentData->{
String fieldValue=amendmentData.getFileValue();
if(fieldValue!=null){
documentService.validateDocument(Long.valueOf(fieldValue));
}
});
applicationAmendmentRequestEntity.setAmendmentDocument(Utils.convertListToJsonString(amendmentFieldRequest));
}
public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity,ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity,VersionActionTypeEnum actionTypeEnum) { public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity,ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity,VersionActionTypeEnum actionTypeEnum) {
ApplicationAmendmentRequestEntity applicationAmendmentRequest = applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity); ApplicationAmendmentRequestEntity applicationAmendmentRequest = applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
@@ -320,12 +361,31 @@ public class ApplicationAmendmentRequestDao {
List<AmendmentFormField> amendmentFormFields = Utils.convertJsonStringToList( List<AmendmentFormField> amendmentFormFields = Utils.convertJsonStringToList(
applicationAmendmentRequestEntity.getFormFields(), AmendmentFormField.class); applicationAmendmentRequestEntity.getFormFields(), AmendmentFormField.class);
Map<String, ApplicationFormFieldEntity> formFieldEntityMap = getApplicationFormFieldEntityMap(applicationAmendmentRequestEntity, amendmentFormFields); Map<String, ApplicationFormFieldEntity> formFieldEntityMap = getApplicationFormFieldEntityMap(applicationAmendmentRequestEntity, amendmentFormFields);
List<AmendmentFieldRequest> amendmentFieldRequests = Utils.convertJsonStringToList(applicationAmendmentRequestEntity.getAmendmentDocument(),AmendmentFieldRequest.class);
if (amendmentFieldRequests != null) {
List<AmendmentDocumentResponse> amendmentDocumentResponses = amendmentFieldRequests.stream()
.map(this::createAmendmentDocumentResponse)
.toList();
response.setAmendmentDocuments(amendmentDocumentResponses);
}
processFormFields(amendmentFormFields, fieldIdToLabelMap, formFieldEntityMap, response); processFormFields(amendmentFormFields, fieldIdToLabelMap, formFieldEntityMap, response);
return response; return response;
} }
private AmendmentDocumentResponse createAmendmentDocumentResponse(AmendmentFieldRequest amendmentFieldRequest) {
AmendmentDocumentResponse amendmentDocumentResponse = new AmendmentDocumentResponse();
amendmentDocumentResponse.setFieldId(amendmentFieldRequest.getFieldId());
amendmentDocumentResponse.setNameValue(amendmentFieldRequest.getNameValue());
amendmentDocumentResponse.setIsValid(amendmentFieldRequest.getIsValid());
DocumentEntity documentEntity = documentService.validateDocument(Long.valueOf(amendmentFieldRequest.getFileValue()));
DocumentResponseBean responseBean = applicationEvaluationDao.createDocumentResponseBean(documentEntity);
amendmentDocumentResponse.setFileValue(responseBean);
return amendmentDocumentResponse;
}
private ApplicationAmendmentRequestResponse initializeBasicResponse(ApplicationAmendmentRequestEntity entity) { private ApplicationAmendmentRequestResponse initializeBasicResponse(ApplicationAmendmentRequestEntity entity) {
ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse(); ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse();
response.setId(entity.getId()); response.setId(entity.getId());
@@ -397,6 +457,7 @@ public class ApplicationAmendmentRequestDao {
responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
return responseBean; return responseBean;
}) })
.toList(); .toList();
@@ -518,6 +579,7 @@ public class ApplicationAmendmentRequestDao {
} }
existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
setAmendmentDocuments(updateRequest.getAmendmentDocuments(),existingApplicationAmendment);
ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE); ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE);
ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment);
log.info("Application Amendment updated successfully: {}", response); log.info("Application Amendment updated successfully: {}", response);
@@ -584,7 +646,7 @@ public class ApplicationAmendmentRequestDao {
String fieldId) { String fieldId) {
AmendmentFormField amendmentFormField = amendmentFormFieldMap.get(fieldId); AmendmentFormField amendmentFormField = amendmentFormFieldMap.get(fieldId);
if (amendmentFormField == null) { if (amendmentFormField == null) {
throw new CustomValidationException(Status.BAD_REQUEST, GepafinConstant.APPLICATION_FORM_FIELD_NOT_FOUND); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_FORM_FIELD_NOT_FOUND));
} }
return amendmentFormField; return amendmentFormField;
} }

View File

@@ -813,7 +813,7 @@ public class ApplicationDao {
if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) { if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) {
callService.validatePublishedCall(applicationEntity.getCall().getId(), userEntity.getHub().getId()); callService.validatePublishedCall(applicationEntity.getCall().getId(), userEntity.getHub().getId());
Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub());
ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity, protocolNumber, userEntity.getHub().getId()); ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(applicationEntity, protocolNumber, userEntity.getHub().getId(),true);
applicationEntity.setProtocol(protocolEntity); applicationEntity.setProtocol(protocolEntity);
applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue()); applicationEntity.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue());
applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));

View File

@@ -323,6 +323,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean); documentResponseBeans.add(responseBean);
}); });
} }
@@ -436,6 +437,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean); documentResponseBeans.add(responseBean);
allDocumentsDeleted[0] = false; allDocumentsDeleted[0] = false;
} }
@@ -962,7 +964,7 @@ public class ApplicationEvaluationDao {
} }
private DocumentResponseBean createDocumentResponseBean(DocumentEntity documentEntity) { public DocumentResponseBean createDocumentResponseBean(DocumentEntity documentEntity) {
DocumentResponseBean responseBean = new DocumentResponseBean(); DocumentResponseBean responseBean = new DocumentResponseBean();
responseBean.setId(documentEntity.getId()); responseBean.setId(documentEntity.getId());
responseBean.setName(documentEntity.getFileName()); responseBean.setName(documentEntity.getFileName());
@@ -972,6 +974,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
return responseBean; return responseBean;
} }
@@ -1044,6 +1047,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean); documentResponseBeans.add(responseBean);
}); });
} }
@@ -1294,6 +1298,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
return responseBean; return responseBean;
} }
@@ -1420,6 +1425,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean); documentResponseBeans.add(responseBean);
}); });
} }

View File

@@ -5,9 +5,11 @@ import com.amazonaws.services.s3.model.GetObjectRequest;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import feign.FeignException; import feign.FeignException;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.config.jwt.TokenProvider;
import net.gepafin.tendermanagement.constants.AppointmentApiConstant; import net.gepafin.tendermanagement.constants.AppointmentApiConstant;
import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEntity;
@@ -125,86 +127,166 @@ public class AppointmentDao {
@Autowired @Autowired
private LoggingUtil loggingUtil; private LoggingUtil loggingUtil;
@Autowired
private TokenProvider tokenProvider;
private final Map<Long, ExecutorService> executorMap = new ConcurrentHashMap<>(); private final Map<Long, ExecutorService> executorMap = new ConcurrentHashMap<>();
private final ConcurrentHashMap<Long, ExecutorService> threadForDocumentMap = new ConcurrentHashMap<>();
private static final ThreadLocal<Long> threadLocalHubId = new ThreadLocal<>();
public NdgResponse checkNdgForAppointment(Long applicationId) { public NdgResponse checkNdgForAppointment(Long applicationId) {
ApplicationEntity application = applicationService.validateApplication(applicationId);
NdgResponse ndgResponse = new NdgResponse();
if (application.getNdgStatus() != null && application.getNdgStatus().equalsIgnoreCase(GepafinConstant.NDG_IN_PROGRESS)) {
throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_GENERATION_IS_IN_PROGRESS));
}
if (application.getNdgStatus() != null && application.getNdgStatus().equalsIgnoreCase(GepafinConstant.NDG_GENERATED) && application.getNdg() != null) {
ndgResponse.setNdg(application.getNdg());
return ndgResponse;
}
// Update application status
application.setNdgStatus(GepafinConstant.NDG_IN_PROGRESS);
applicationRepository.save(application);
// Start async processing
startAsyncNdgProcessing(applicationId);
throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_GENERATION_IS_IN_PROGRESS));
}
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;
}
// 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) {
// Validate application, company, and hub
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.");
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NO_NDG_FOR_ANOTHER_HUB));
}
try { try {
NdgResponse ndgResponseToReturn = new NdgResponse();
// Validate application, company, and hub
ApplicationEntity application = applicationService.validateApplication(applicationId);
if (application.getNdgStatus() != null && application.getNdgStatus().equalsIgnoreCase(GepafinConstant.NDG_IN_PROGRESS)) {
throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_GENERATION_IS_IN_PROGRESS));
}
//cloned for old application data
ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
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.");
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NO_NDG_FOR_ANOTHER_HUB));
}
// Check if NDG and idVisura are already present
if (isNdgAndIdVisuraPresent(application)) {
log.info("NDG already exist for applicationId: {}", applicationId);
ndgResponseToReturn.setNdg(application.getNdg());
return ndgResponseToReturn;
}
// Authenticate and fetch token if required // Authenticate and fetch token if required
if (hub.getAppointmentAuthTokenId() == null && hub.getAreaCode() == null) { if (hub.getAppointmentAuthTokenId() == null || hub.getAreaCode() == null) {
hub = authenticateAndSaveToken(hub); authenticateAndSaveToken(hub);
} }
String authorizationToken = getBearerToken(hub); String authorizationToken = getBearerToken(hub);
// Try retrieving NDG by VAT number // Try retrieving NDG by VAT number
AppointmentLoginResponse ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application); AppointmentLoginResponse ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application);
//For testing purpose Commenting it
if (isNdgValid(ndgResponse.getNdg())) { if (isNdgValid(ndgResponse.getNdg())) {
saveNdgAndIdVisura(application, company, ndgResponse.getNdg(), null); saveNdgAndIdVisura(application, company, ndgResponse.getNdg(), null);
ndgResponseToReturn.setNdg(application.getNdg()); log.info("NDG successfully generated for applicationId: {}", applicationId);
return ndgResponseToReturn; } else {
// If NDG isn't immediately available, start polling
handleNdgPolling(application, company, hub, authorizationToken);
} }
return getNdgResponse(company, authorizationToken, hub, application, ndgResponseToReturn, oldApplicationData);
} catch (FeignException e) {
log.error("Error in feign client call during NDG handling: {}", e.getMessage(), e);
Utils.callException(e.status(), e);
} catch (CustomValidationException e) {
log.info("Custom validation exception: {}", e.getMessage());
throw e;
} catch (Exception e) { } catch (Exception e) {
log.error("Error during NDG handling: {}", e.getMessage(), e); log.error("Error during NDG generation for applicationId: {}", applicationId, e);
throw new RuntimeException("Error during fetching NDG.");
} }
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_IN_GENERATING_NDG_TRY_AGAIN));
} }
private NdgResponse getNdgResponse(CompanyEntity company, String authorizationToken, HubEntity hub, ApplicationEntity application, NdgResponse ndgResponseToReturn, private void handleNdgPolling(ApplicationEntity application, CompanyEntity company, HubEntity hub, String authorizationToken) {
ApplicationEntity oldApplicationData) {
// Create Visura if NDG is not found
AppointmentLoginResponse visuraResponse = createVisura(company, authorizationToken, hub);
if (isNdgValid(visuraResponse.getNdg())) {
saveNdgAndIdVisura(application, company, visuraResponse.getNdg(), visuraResponse.getIdVisura());
ndgResponseToReturn.setNdg(application.getNdg());
} else if (visuraResponse.getIdVisura() != null) {
application.setNdgStatus(GepafinConstant.NDG_IN_PROGRESS);
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
applicationRepository.save(application);
/** This code is responsible for adding a version history log for the "Updating ndg status in application" operation. **/ try {
loggingUtil.addVersionHistory( log.info("Starting NDG polling for applicationId: {}", application.getId());
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(application).build()); long startTime = System.currentTimeMillis();
startNdgPollingTask(application, company, hub); while (true) {
throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_GENERATION_IS_IN_PROGRESS)); if (application.getNdg() != null) {
log.info("NDG retrieved for applicationId: {}", application.getId());
break;
}
try {
// Fetch Visura list and attempt to parse NDG
String visuraListJson = getVisuraList(application.getIdVisura(), authorizationToken, application, hub);
String ndg = parseNdgFromVisuraListResponse(visuraListJson);
if (isNdgValid(ndg)) {
// CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company);
// ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
company.setNdg(ndg);
application.setNdg(ndg);
application.setNdgStatus(GepafinConstant.NDG_GENERATED);
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
applicationRepository.save(application);
companyRepository.save(company);
log.info("NDG saved successfully for applicationId: {}", application.getId());
// /** This code is responsible for adding a version history log for the "update application ndg code, status, and Id visura"
// operation. **/
// loggingUtil.addVersionHistory(
// VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData)
// .newData(application).build());
//
// /** This code is responsible for adding a version history log for the "update company ndg code" operation. **/
// loggingUtil.addVersionHistory(
// VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyData)
// .newData(company).build());
break;
}
// Check if polling has timed out
if (System.currentTimeMillis() - startTime > TimeUnit.HOURS.toMillis(2)) {
log.warn("NDG polling timed out for applicationId: {}", application.getId());
application.setNdgStatus(GepafinConstant.NDG_FAILED);
applicationRepository.save(application);
break;
}
// 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;
} catch (Exception e) {
log.error("Error during NDG polling for applicationId: {}", application.getId(), e);
}
}
} finally {
log.info("NDG polling completed for applicationId: {}", application.getId());
} }
return ndgResponseToReturn;
} }
private static String getBearerToken(HubEntity hub) { private static String getBearerToken(HubEntity hub) {
@@ -212,102 +294,6 @@ public class AppointmentDao {
return "Bearer " + hub.getAppointmentAuthTokenId(); return "Bearer " + hub.getAppointmentAuthTokenId();
} }
private void startNdgPollingTask(ApplicationEntity application, CompanyEntity company, HubEntity hub) {
//cloned for all data
ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company);
// Check if a thread is already running for this application
if (executorMap.containsKey(application.getId())) {
log.warn("Polling task already running for applicationId: {}", application.getId());
return;
}
// Create a dedicated thread (single-threaded executor) for this application
ExecutorService executor = Executors.newSingleThreadExecutor(runnable -> {
Thread thread = new Thread(runnable);
thread.setName(GepafinConstant.POLLING_THREAD_NAME + application.getId());
return thread;
});
executorMap.put(application.getId(), executor);
// Submit polling task to this thread
executor.submit(() -> {
try {
log.info("Polling task started for applicationId: {} on thread: {}", application.getId(), Thread.currentThread().getName());
long startTime = System.currentTimeMillis();
while (true) {
if (application.getNdg() != null)
break;
try {
String visuraListJson = getVisuraList(application.getIdVisura(), hub.getAppointmentAuthTokenId(), application, hub);
String ndg = parseNdgFromVisuraListResponse(visuraListJson);
if (isNdgValid(ndg)) {
company.setNdg(ndg);
application.setNdgStatus(GepafinConstant.NDG_GENERATED);
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
application.setNdg(ndg);
applicationRepository.save(application);
companyRepository.save(company);
log.info("NDG obtained for applicationId: {} and saved successfully.", application.getId());
break; // Exit the loop after successful NDG retrieval
} else {
log.warn("NDG not found for applicationId: {} in Visura List API response.", application.getId());
}
// Check if polling time has exceeded the limit
if (System.currentTimeMillis() - startTime > TimeUnit.HOURS.toMillis(2)) {
log.warn("Polling timed out for applicationId: {}", application.getId());
// Mark NDG status as FAILED for this application
application.setNdgStatus(GepafinConstant.NDG_FAILED);
application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
applicationRepository.save(application);
log.info("NDG status marked as FAILED for applicationId: {}", application.getId());
break;
}
// Wait before the next polling attempt
Thread.sleep(TimeUnit.MINUTES.toMillis(15));
} catch (InterruptedException e) {
log.warn("Polling task interrupted for applicationId: {}", application.getId());
Thread.currentThread().interrupt();
break;
} catch (Exception e) {
log.error("Error during NDG polling for applicationId: {}", application.getId(), e);
}
}
} finally {
// Cleanup: Shut down the thread for this application
executor.shutdown();
executorMap.remove(application.getId());
log.info("Polling task completed and thread shut down for applicationId: {}", application.getId());
}
});
/** This code is responsible for adding a version history log for the "Update application ndgCode and ndgStatus" operation. **/
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(application).build());
/** This code is responsible for adding a version history log for the "Update company ndgCode" operation. **/
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyData).newData(company).build());
}
private boolean isNdgAndIdVisuraPresent(ApplicationEntity application) {
String ndg = application.getNdg();
String idVisura = application.getIdVisura();
if (ndg != null && idVisura == null) {
return true;
} else if (ndg == null && idVisura != null) {
return false;
} else
return ndg != null;
}
private boolean isNdgValid(String ndg) { private boolean isNdgValid(String ndg) {
return ndg != null && !ndg.isEmpty(); return ndg != null && !ndg.isEmpty();
@@ -316,8 +302,8 @@ public class AppointmentDao {
private void saveNdgAndIdVisura(ApplicationEntity application, CompanyEntity company, String ndg, String idVisura) { private void saveNdgAndIdVisura(ApplicationEntity application, CompanyEntity company, String ndg, String idVisura) {
//cloned for old application and company data //cloned for old application and company data
ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application); // ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company); // CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company);
application.setNdg(ndg); application.setNdg(ndg);
application.setIdVisura(idVisura); application.setIdVisura(idVisura);
@@ -327,12 +313,13 @@ public class AppointmentDao {
companyRepository.save(company); companyRepository.save(company);
applicationRepository.save(application); applicationRepository.save(application);
/** This code is responsible for adding a version history log for the "update application ndg code, status, and Id visura" operation. **/ // /** This code is responsible for adding a version history log for the "update application ndg code, status, and Id visura" operation. **/
loggingUtil.addVersionHistory( // loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(application).build()); // VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(application).build());
//
/** This code is responsible for adding a version history log for the "update company ndg code" operation. **/ // /** This code is responsible for adding a version history log for the "update company ndg code" operation. **/
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyData).newData(company).build()); // loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyData).newData
// (company).build());
log.info("NDG saved for applicationId: {}, {}", application.getId(), application.getNdg()); log.info("NDG saved for applicationId: {}, {}", application.getId(), application.getNdg());
} }
@@ -361,7 +348,7 @@ public class AppointmentDao {
private HubEntity authenticateAndSaveToken(HubEntity hub) { private HubEntity authenticateAndSaveToken(HubEntity hub) {
HubEntity oldHubData = Utils.getClonedEntityForData(hub); // HubEntity oldHubData = Utils.getClonedEntityForData(hub);
try { try {
//code to generate token with payload having "iat" epoch timestamp and secret key with no expiry and send in below method call //code to generate token with payload having "iat" epoch timestamp and secret key with no expiry and send in below method call
String authJwtToken = Utils.generateAuthTokenForLoginToOdessa(); String authJwtToken = Utils.generateAuthTokenForLoginToOdessa();
@@ -369,8 +356,9 @@ public class AppointmentDao {
hub.setAuthToken(authJwtToken); hub.setAuthToken(authJwtToken);
hubRepository.save(hub); hubRepository.save(hub);
/** This code is responsible for adding a version history log for the "Updating auth token for login api in hub" operation. **/ // /** This code is responsible for adding a version history log for the "Updating auth token for login api in hub" operation. **/
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldHubData).newData(hub).build()); // loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldHubData).newData
// (hub).build());
// Prepare the request body (adjust if necessary for login API) // Prepare the request body (adjust if necessary for login API)
Map<String, Object> body = Collections.emptyMap(); Map<String, Object> body = Collections.emptyMap();
@@ -389,10 +377,12 @@ public class AppointmentDao {
hub.setAreaCode(parsedResponse.getAreaCode()); hub.setAreaCode(parsedResponse.getAreaCode());
hubRepository.save(hub); hubRepository.save(hub);
/** This code is responsible for adding a version history log for the "inserting token and areaCode from login odessa response for appointment flow api's" // /** This code is responsible for adding a version history log for the "inserting token and areaCode from login odessa response for
* operation. **/ // appointment flow api's"
loggingUtil.addVersionHistory( // * operation. **/
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldHubData).newData(hub).build()); // loggingUtil.addVersionHistory(
// VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldHubData).newData(hub)
// .build());
log.info("Saved new authToken and areaCode for Hub."); log.info("Saved new authToken and areaCode for Hub.");
return hub; return hub;
@@ -419,7 +409,7 @@ public class AppointmentDao {
// Parse and return the NDG response // Parse and return the NDG response
return parseNdgResponse(responseJson); return parseNdgResponse(responseJson);
} catch (FeignException.Forbidden forbiddenException) { } catch (FeignException.Forbidden forbiddenException) {
log.error("403 Forbidden received while retrieving NDG. Regenerating token..."); logForbiddenError();
// Regenerate the token and retry // Regenerate the token and retry
String newAuthorizationToken = regenerateTokenAndSave(hub); String newAuthorizationToken = regenerateTokenAndSave(hub);
return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application); return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application);
@@ -448,7 +438,7 @@ public class AppointmentDao {
String responseJson = Utils.convertObjectToJson(response.getBody()); String responseJson = Utils.convertObjectToJson(response.getBody());
return parseVisuraResponse(responseJson); return parseVisuraResponse(responseJson);
} catch (FeignException.Forbidden forbiddenException) { } catch (FeignException.Forbidden forbiddenException) {
log.error("403 Forbidden received while retrieving NDG. Regenerating token..."); logForbiddenError();
// Regenerate the token and retry // Regenerate the token and retry
String newAuthorizationToken = regenerateTokenAndSave(hub); String newAuthorizationToken = regenerateTokenAndSave(hub);
return createVisura(company, newAuthorizationToken, hub); return createVisura(company, newAuthorizationToken, hub);
@@ -458,6 +448,11 @@ public class AppointmentDao {
} }
} }
private static void logForbiddenError() {
log.error("403 Forbidden received while retrieving NDG. Regenerating token...");
}
private static AppointmentNdgRequest getAppointmentNdgRequest(String vatNumber) { private static AppointmentNdgRequest getAppointmentNdgRequest(String vatNumber) {
AppointmentNdgRequest request = new AppointmentNdgRequest(); AppointmentNdgRequest request = new AppointmentNdgRequest();
@@ -733,87 +728,101 @@ public class AppointmentDao {
return appointmentCreationRequest; return appointmentCreationRequest;
} }
public DocumentUploadResponse uploadDocumentToExternalSystem(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest, Long applicationId) { public DocumentUploadResponse uploadDocumentToExternalSystem(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
// Check if the document is already being processed
DocumentUploadResponse response = new DocumentUploadResponse();
DocumentEntity systemDoc = documentDao.validateDocument(documentId); DocumentEntity systemDoc = documentDao.validateDocument(documentId);
ApplicationEntity application = getApplicationEntityForDocument(applicationId, systemDoc); Claims claims = tokenProvider.getClaimsFromToken(tokenProvider.extractTokenFromRequest(request));
Long hubId = Utils.extractHubIdFromPayload(claims.getSubject());
//cloned for old document data if (systemDoc.getDocumentAttachmentId() != null) {
DocumentEntity oldDocumentEntity = Utils.getClonedEntityForData(systemDoc); // If the documentAttachmentId is already set, return the response
log.info("Document already uploaded with documentAttachmentId: {}", systemDoc.getDocumentAttachmentId());
if (!docToExternalSystemRequest.getInput().getAttributes().getNdg().equalsIgnoreCase(application.getNdg())) { DocumentUploadResponse response = new DocumentUploadResponse();
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NDG_NOT_MATCHED_OR_NOT_FOUND)); response.setDocumentAttachmentId(systemDoc.getDocumentAttachmentId());
return response;
} }
// Check if a thread is already running for this document upload
if (threadForDocumentMap.containsKey(documentId)) {
log.warn("Document upload already running for documentId: {}", documentId);
throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_UPLOADING_IN_PROGRESS));
}
// Start the upload process in the background
ExecutorService executor = Executors.newSingleThreadExecutor(runnable -> {
Thread thread = new Thread(runnable);
thread.setName(GepafinConstant.ASYNC_DOCUMENT_UPLOAD_NAME + documentId);
return thread;
});
threadForDocumentMap.put(documentId, executor);
Long hubId = application.getHubId(); executor.submit(() -> {
threadLocalHubId.set(hubId);
try {
log.info("Starting async document upload for documentId: {}", documentId);
uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest);
} catch (Exception e) {
log.error("Error in async document upload for documentId: {}", documentId, e);
} finally {
// Cleanup resources
ExecutorService executorToShutdown = threadForDocumentMap.remove(documentId);
if (executorToShutdown != null) {
executorToShutdown.shutdown();
threadLocalHubId.remove();
}
log.info("Async document upload completed for documentId: {}", documentId);
}
});
// Return an immediate response indicating the process is in progress
throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_UPLOADING_IN_PROGRESS));
}
private void uploadDocumentToExternalSystemSync(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
// Synchronous upload logic
DocumentEntity systemDoc = documentDao.validateDocument(documentId);
Long hubId = threadLocalHubId.get();
HubEntity hub = hubRepository.findByHubId(hubId); HubEntity hub = hubRepository.findByHubId(hubId);
if (!hub.getUniqueUuid().equals(defaultHubUuid)) { if (!hub.getUniqueUuid().equals(defaultHubUuid)) {
log.info("Document cannot be uploaded for another Hub, it is default for Gepafin."); log.info("Document cannot be uploaded for another Hub, it is default for Gepafin.");
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NO_DOCUMENT_UPLOAD_FOR_ANOTHER_HUB)); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NO_DOCUMENT_UPLOAD_FOR_ANOTHER_HUB));
} }
log.info("Got Document in system {}", systemDoc);
log.info("Got Document in system: {}", systemDoc);
String oldUrl = systemDoc.getFilePath(); String oldUrl = systemDoc.getFilePath();
log.info("Processing {}", oldUrl);
String authorizationToken = getBearerToken(hub); String authorizationToken = getBearerToken(hub);
try { try {
File localFile = downloadFileFromS3(oldUrl); File localFile = downloadFileFromS3(oldUrl);
MultipartFile multipartFile = convertFileToMultipartFile(localFile); MultipartFile multipartFile = convertFileToMultipartFile(localFile);
UploadDocToExternalSystemRequest externalSystemRequest = new UploadDocToExternalSystemRequest(); UploadDocToExternalSystemRequest externalSystemRequest = new UploadDocToExternalSystemRequest();
externalSystemRequest.setInput(getUploadDocumentInput(docToExternalSystemRequest));
UploadDocToExternalSystemRequest.Input input = getUploadDocumentInput(docToExternalSystemRequest);
externalSystemRequest.setInput(input);
String uploadDocRequest = Utils.convertObjectToJson(externalSystemRequest); String uploadDocRequest = Utils.convertObjectToJson(externalSystemRequest);
ResponseEntity<Object> uploadedDocumentData = appointmentApiService.uploadDocumentToExternalSystemForAppointment(authorizationToken, context, uploadDocRequest, ResponseEntity<Object> uploadedDocumentData = appointmentApiService.uploadDocumentToExternalSystemForAppointment(authorizationToken, context, uploadDocRequest,
multipartFile); multipartFile);
String responseData = Utils.convertObjectToJson(uploadedDocumentData.getBody());
DocumentUploadResponse parsedDocumentUploadResponse = parseDocumentUploadResponse(responseData);
if (parsedDocumentUploadResponse == null) { String responseData = Utils.convertObjectToJson(uploadedDocumentData.getBody());
DocumentUploadResponse parsedResponse = parseDocumentUploadResponse(responseData);
if (parsedResponse == null) {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_UPLOADING_DOCUMENT)); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_UPLOADING_DOCUMENT));
} }
systemDoc.setDocumentAttachmentId(parsedDocumentUploadResponse.getDocumentAttachmentId()); // Save the documentAttachmentId to the database
systemDoc.setDocumentAttachmentId(parsedResponse.getDocumentAttachmentId());
documentRepository.save(systemDoc); documentRepository.save(systemDoc);
/** This code is responsible for adding a version history log for the "Update document with document attachment id" operation. **/ log.info("Document uploaded successfully to external system: {}", parsedResponse);
loggingUtil.addVersionHistory(
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldDocumentEntity).newData(systemDoc).build());
log.info("Document uploaded successfully to external system : {}", parsedDocumentUploadResponse);
response.setDocumentAttachmentId(systemDoc.getDocumentAttachmentId());
return response;
} catch (FeignException.Forbidden forbiddenException) { } catch (FeignException.Forbidden forbiddenException) {
log.error("403 Forbidden received while uploading document to external system. Regenerating token..."); log.error("403 Forbidden received while uploading document. Regenerating token...");
regenerateTokenAndSave(hub); regenerateTokenAndSave(hub);
return uploadDocumentToExternalSystem(systemDoc.getSourceId(), docToExternalSystemRequest, applicationId); uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest);
} catch (Exception e) { } catch (Exception e) {
log.error("Exception in uploading document to external system {}", e.getMessage()); log.error("Exception during document upload: {}", e.getMessage(), e);
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.EXTERNAL_DOCUMENT_UPLOAD_FAILURE_MSG)); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.EXTERNAL_DOCUMENT_UPLOAD_FAILURE_MSG));
} }
} }
private ApplicationEntity getApplicationEntityForDocument(Long applicationId, DocumentEntity systemDoc) {
if (systemDoc.getDocumentAttachmentId() != null) {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.DOCUMENT_ALREADY_UPLOADED));
}
ApplicationEntity application;
if (systemDoc.getSource().equalsIgnoreCase(DocumentSourceTypeEnum.APPLICATION.getValue()) && Objects.equals(systemDoc.getSourceId(), applicationId)) {
application = applicationService.validateApplication(systemDoc.getSourceId());
} else {
throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.PROVIDE_VALID_APPLICATION_DOC_ID));
}
return application;
}
private UploadDocToExternalSystemRequest.Input getUploadDocumentInput(UploadDocToExternalSystemRequest docToExternalSystemRequest) { private UploadDocToExternalSystemRequest.Input getUploadDocumentInput(UploadDocToExternalSystemRequest docToExternalSystemRequest) {

View File

@@ -4,6 +4,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.enums.ProtocolTypeEnum;
import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum;
import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.LoggingUtil;
@@ -42,7 +43,7 @@ public class ProtocolDao {
return (maxProtocolNumber != null) ? maxProtocolNumber + 1 : startNumber; return (maxProtocolNumber != null) ? maxProtocolNumber + 1 : startNumber;
} }
public ProtocolEntity createProtocolEntity(ApplicationEntity applicationEntity,Long protocolNumber, Long hubId){ public ProtocolEntity createProtocolEntity(ApplicationEntity applicationEntity,Long protocolNumber, Long hubId,Boolean isForApplication){
ProtocolEntity protocolEntity=new ProtocolEntity(); ProtocolEntity protocolEntity=new ProtocolEntity();
protocolEntity.setCall(applicationEntity.getCall().getId()); protocolEntity.setCall(applicationEntity.getCall().getId());
LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now());
@@ -51,6 +52,11 @@ public class ProtocolDao {
protocolEntity.setTime(LocalTime.now()); protocolEntity.setTime(LocalTime.now());
protocolEntity.setApplicationId(applicationEntity.getId()); protocolEntity.setApplicationId(applicationEntity.getId());
protocolEntity.setHubId(hubId); protocolEntity.setHubId(hubId);
if(Boolean.TRUE.equals(isForApplication)){
protocolEntity.setType(ProtocolTypeEnum.INPUT.getValue());
}else {
protocolEntity.setType(ProtocolTypeEnum.OUTPUT.getValue());
}
protocolRepository.save(protocolEntity); protocolRepository.save(protocolEntity);
/** This code is responsible for adding a version history log for "create protocol" operation. **/ /** This code is responsible for adding a version history log for "create protocol" operation. **/

View File

@@ -50,4 +50,7 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity {
@Column(name = "end_date") @Column(name = "end_date")
private LocalDateTime endDate; private LocalDateTime endDate;
@Column(name = "amendment_document")
private String amendmentDocument;
} }

View File

@@ -28,4 +28,7 @@ public class ProtocolEntity extends BaseEntity {
@Column(name="HUB_ID") @Column(name="HUB_ID")
private Long hubId; private Long hubId;
@Column(name = "type")
private String type;
} }

View File

@@ -0,0 +1,24 @@
package net.gepafin.tendermanagement.enums;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ProtocolTypeEnum {
INPUT("INPUT"),
OUTPUT("OUTPUT");
private String value;
ProtocolTypeEnum(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
@Override
public String toString() {
return String.valueOf(value);
}
}

View File

@@ -0,0 +1,13 @@
package net.gepafin.tendermanagement.model.request;
import lombok.Data;
@Data
public class AmendmentFieldRequest {
private String fieldId;
private String nameValue;
private String fileValue;
private Boolean isValid = false;
}

View File

@@ -11,4 +11,5 @@ public class ApplicationAmendmentRequest {
private Long responseDays; private Long responseDays;
private Boolean isSendNotification; private Boolean isSendNotification;
private Boolean isSendEmail; private Boolean isSendEmail;
private List<AmendmentFieldRequest> amendmentDocument;
} }

View File

@@ -8,4 +8,5 @@ import lombok.Data;
public class ApplicationAmendmentRequestBean { public class ApplicationAmendmentRequestBean {
private String note; private String note;
private List<ApplicationFormFieldRequestBean> applicationFormFields; private List<ApplicationFormFieldRequestBean> applicationFormFields;
private List<AmendmentFieldRequest> amendmentDocuments;
} }

View File

@@ -0,0 +1,12 @@
package net.gepafin.tendermanagement.model.response;
import lombok.Data;
@Data
public class AmendmentDocumentResponse {
private String fieldId;
private String nameValue;
private DocumentResponseBean fileValue;
private Boolean isValid = false;
}

View File

@@ -21,6 +21,7 @@ public class ApplicationAmendmentRequestResponse {
private String beneficiaryName; private String beneficiaryName;
private List<AmendmentFormFieldResponse> formFields; private List<AmendmentFormFieldResponse> formFields;
private List<ApplicationFormFieldResponseBean> applicationFormFields; private List<ApplicationFormFieldResponseBean> applicationFormFields;
private List<AmendmentDocumentResponse> amendmentDocuments;
private Long applicationId; private Long applicationId;
private Long applicationEvaluationId; private Long applicationEvaluationId;
private LocalDateTime evaluationEndDate; private LocalDateTime evaluationEndDate;

View File

@@ -25,4 +25,6 @@ public class DocumentResponseBean {
private LocalDateTime createdDate; private LocalDateTime createdDate;
private LocalDateTime updatedDate; private LocalDateTime updatedDate;
private String documentAttachmentId;
} }

View File

@@ -12,5 +12,5 @@ public interface AppointmentService {
AppointmentCreationResponse createAppointmentForApplication(HttpServletRequest request, Long applicationId, CreateAppointmentRequest createAppointmentRequest); AppointmentCreationResponse createAppointmentForApplication(HttpServletRequest request, Long applicationId, CreateAppointmentRequest createAppointmentRequest);
DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest, Long applicationId); DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest);
} }

View File

@@ -30,9 +30,8 @@ public class AppointmentServiceImpl implements AppointmentService {
} }
@Override @Override
public DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest, public DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
Long applicationId) {
return appointmentDao.uploadDocumentToExternalSystem(documentId, docToExternalSystemRequest, applicationId); return appointmentDao.uploadDocumentToExternalSystem(documentId, docToExternalSystemRequest);
} }
} }

View File

@@ -9,7 +9,6 @@ import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.UserActionEntity; import net.gepafin.tendermanagement.entities.UserActionEntity;
import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.entities.VersionHistoryEntity; import net.gepafin.tendermanagement.entities.VersionHistoryEntity;
import net.gepafin.tendermanagement.enums.VersionActionTypeEnum;
import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.UserActionRequest;
import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
import net.gepafin.tendermanagement.repositories.UserActionsRepository; import net.gepafin.tendermanagement.repositories.UserActionsRepository;

View File

@@ -19,12 +19,15 @@ import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import io.jsonwebtoken.Claims;
import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany; import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
import org.apache.commons.collections4.MapUtils; import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -60,6 +63,9 @@ import static org.apache.commons.lang3.StringUtils.isEmpty;
public class Utils { public class Utils {
// @Autowired
// private static TokenProvider tokenProvider;
public static final Logger log = LoggerFactory.getLogger(Utils.class); public static final Logger log = LoggerFactory.getLogger(Utils.class);
private static final ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) private static final ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
@@ -612,4 +618,55 @@ public class Utils {
throw new RuntimeException("Failed to generate JWT token", e); throw new RuntimeException("Failed to generate JWT token", e);
} }
} }
// public static void setHttpServletRequestForNdgProcess(HttpServletRequest originalRequest) {
//
// // Validate original request
// if (originalRequest == null) {
// throw new IllegalArgumentException("Original request cannot be null.");
// }
//
// // Create a mock request
// Claims tokenClaims = tokenProvider.getClaimsFromToken(tokenProvider.extractTokenFromRequest(originalRequest));
// MockHttpServletRequest mockRequest = new MockHttpServletRequest();
// mockRequest.setRequestURI(originalRequest.getRequestURI());
// mockRequest.setMethod(originalRequest.getMethod());
//
// // Copy essential headers and attributes from the original request
// Enumeration<String> headerNames = originalRequest.getHeaderNames();
// while (headerNames.hasMoreElements()) {
// String headerName = headerNames.nextElement();
// String headerValue = originalRequest.getHeader(headerName);
// if (headerValue != null) {
// mockRequest.addHeader(headerName, headerValue);
// }
// }
//
// // Set a specific attribute if required
// if (originalRequest.getAttribute(GepafinConstant.USER_ACTION_ID) != null) {
// mockRequest.setAttribute(GepafinConstant.USER_ACTION_ID, originalRequest.getAttribute(GepafinConstant.USER_ACTION_ID));
// }
//
// ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest);
// RequestContextHolder.setRequestAttributes(attributes);
// // Log successful context setting
// log.info("Successfully set mock request for NDG process with URI: {}", mockRequest.getRequestURI());
// }
public static Long extractHubIdFromPayload(String payload) {
Long hubId;
try {
String[] parts = payload.split(":");
if (parts.length > 2) {
hubId = Long.valueOf(parts[2]);
return hubId;
} else {
hubId = null;
}
} catch (Exception e) {
throw new RuntimeException("No Hub id present in payload", e);
}
return null;
}
} }

View File

@@ -52,9 +52,8 @@ public interface AppointmentApi {
@ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })), @ExampleObject(value = ErrorConstants.UNAUTHORIZED_ERROR_EXAMPLE) })),
@ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) })
@PostMapping(value = "/application/{applicationId}/document/{documentId}", produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "/document/{documentId}", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Response<DocumentUploadResponse>> uploadDocumentToExternalSystem(HttpServletRequest request, ResponseEntity<Response<DocumentUploadResponse>> uploadDocumentToExternalSystem(HttpServletRequest request,
@Parameter(description = "The document id", required = true) @PathVariable(value = "documentId", required = true) Long documentId, @Parameter(description = "The document id", required = true) @PathVariable(value = "documentId", required = true) Long documentId,
@Parameter(description = "The application id", required = true) @PathVariable(value = "applicationId", required = true) Long applicationId,
@RequestBody UploadDocToExternalSystemRequest docToExternalSystemRequest); @RequestBody UploadDocToExternalSystemRequest docToExternalSystemRequest);
} }

View File

@@ -61,14 +61,14 @@ public class AppointmentController implements AppointmentApi {
} }
@Override @Override
public ResponseEntity<Response<DocumentUploadResponse>> uploadDocumentToExternalSystem(HttpServletRequest request, Long documentId, Long applicationId, public ResponseEntity<Response<DocumentUploadResponse>> uploadDocumentToExternalSystem(HttpServletRequest request, Long documentId,
UploadDocToExternalSystemRequest docToExternalSystemRequest) { UploadDocToExternalSystemRequest docToExternalSystemRequest) {
/** This code is responsible for creating user action logs for the "Upload document to external system" operation. **/ /** This code is responsible for creating user action logs for the "Upload document to external system" operation. **/
loggingUtil.logUserAction( loggingUtil.logUserAction(
UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPLOAD).actionContext(UserActionContextEnum.UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM).build()); UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPLOAD).actionContext(UserActionContextEnum.UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM).build());
DocumentUploadResponse documentUploadResponse = appointmentService.uploadDocToExternalSystem(request, documentId, docToExternalSystemRequest, applicationId); DocumentUploadResponse documentUploadResponse = appointmentService.uploadDocToExternalSystem(request, documentId, docToExternalSystemRequest);
return ResponseEntity.status(HttpStatus.OK) return ResponseEntity.status(HttpStatus.OK)
.body(new Response<>(documentUploadResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_UPLOADED_SUCCESSFULLY_TO_EXTERNAL_SYSTEM))); .body(new Response<>(documentUploadResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_UPLOADED_SUCCESSFULLY_TO_EXTERNAL_SYSTEM)));

View File

@@ -1991,7 +1991,7 @@
<column name="document_attachment_id" type="TEXT"/> <column name="document_attachment_id" type="TEXT"/>
</addColumn> </addColumn>
</changeSet> </changeSet>
<changeSet id="12-12-2024_1" author="Rajesh Khore"> <changeSet id="12-12-2024_2" author="Rajesh Khore">
<insert tableName="s3_path_configuration"> <insert tableName="s3_path_configuration">
<column name="type" value="EVALUATION"/> <column name="type" value="EVALUATION"/>
<column name="path" value="call/{call_id}/application/{application_id}/evaluation"/> <column name="path" value="call/{call_id}/application/{application_id}/evaluation"/>
@@ -2018,6 +2018,15 @@
<column name="uploaded_by" type="INTEGER"> <column name="uploaded_by" type="INTEGER">
<!-- <constraints nullable="false"/>--> <!-- <constraints nullable="false"/>-->
</column> </column>
</addColumn>
</changeSet>
<changeSet id="12_12_2024_1" author="Nisha Kashyap">
<addColumn tableName="protocol">
<column name="type" type="VARCHAR(255)"></column>
</addColumn>
<addColumn tableName="application_amendment_request">
<column name="amendment_document" type="TEXT"></column>
</addColumn> </addColumn>
</changeSet> </changeSet>
</databaseChangeLog> </databaseChangeLog>

View File

@@ -320,7 +320,7 @@ atleast.one.id.required=At least one of companyId or applicationId must be provi
ndg.generated = NDG Generated. ndg.generated = NDG Generated.
ndg.available = NDG Available. ndg.available = NDG Available.
ndg.generation.in.progress = NDG generation is in progress. ndg.generation.in.progress = NDG generation is in progress.
ndg.fetch.successfully = NDG fetch successfully. ndg.fetch.successfully = NDG fetched successfully.
appointment.already.created = Appointment Already Created. appointment.already.created = Appointment Already Created.
ndg.not.found.for.this.application.or.invalid = Ndg not found for this application or invalid. ndg.not.found.for.this.application.or.invalid = Ndg not found for this application or invalid.
provide.valid.application.document.id = Provide valid application document id. provide.valid.application.document.id = Provide valid application document id.
@@ -334,3 +334,5 @@ appointment.creation.is.only.for.gepafin = Appointment creation is only allowed
upload.document.is.only.for.gepafin = Document cant be uploaded, this is only available for GEPAFIN Hub. upload.document.is.only.for.gepafin = Document cant be uploaded, this is only available for GEPAFIN Hub.
appointment.created.successfully = Appointment created successfully. appointment.created.successfully = Appointment created successfully.
error.try.again = Service call error while performing the operation. Please try again. error.try.again = Service call error while performing the operation. Please try again.
document.uploading.is.in.progress = Document uploading is in progress.
all.document.checked.and.one.checklist.checked=All document should be checked and at least one checklist should be checked.

View File

@@ -310,7 +310,7 @@ atleast.one.id.required=Almeno uno tra companyId o applicationId deve essere for
#Appointment flow messages #Appointment flow messages
ndg.available = NDG disponibile. ndg.available = NDG disponibile.
ndg.generation.in.progress = La generazione NDG ? in corso. ndg.generation.in.progress = La generazione NDG ? in corso.
ndg.fetch.successfully = Recupero NDG riuscito. ndg.fetch.successfully = NDG recuperato con successo.
appointment.already.created = Appuntamento gi? creato. appointment.already.created = Appuntamento gi? creato.
ndg.not.found.for.this.application.or.invalid = NDG non trovato per questa applicazione o non valido. ndg.not.found.for.this.application.or.invalid = NDG non trovato per questa applicazione o non valido.
provide.valid.application.document.id = Fornisci un ID documento applicativo valido. provide.valid.application.document.id = Fornisci un ID documento applicativo valido.
@@ -324,3 +324,5 @@ appointment.creation.is.only.for.gepafin = La creazione degli appuntamenti ? con
upload.document.is.only.for.gepafin = Il documento non pu? essere caricato, questa operazione ? disponibile solo per il Hub GEPAFIN. upload.document.is.only.for.gepafin = Il documento non pu? essere caricato, questa operazione ? disponibile solo per il Hub GEPAFIN.
appointment.created.successfully = Appuntamento creato con successo. appointment.created.successfully = Appuntamento creato con successo.
error.try.again = Errore di chiamata di servizio durante l'esecuzione dell'operazione. Riprovare. error.try.again = Errore di chiamata di servizio durante l'esecuzione dell'operazione. Riprovare.
document.uploading.is.in.progress = Il documento è in fase di caricamento.
all.document.checked.and.one.checklist.checked=Tutti i documenti devono essere controllati e almeno una checklist deve essere controllata.