diff --git a/pom.xml b/pom.xml
index f3424e44..93a592ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -88,8 +88,8 @@
com.amazonaws
- aws-java-sdk-s3
- 1.12.312
+ aws-java-sdk
+ 1.12.563
diff --git a/src/main/java/net/gepafin/tendermanagement/constants/AppointmentApiConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/AppointmentApiConstant.java
new file mode 100644
index 00000000..15a3444e
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/constants/AppointmentApiConstant.java
@@ -0,0 +1,27 @@
+package net.gepafin.tendermanagement.constants;
+
+public class AppointmentApiConstant {
+
+ public static final String ODESSA_LOGIN = "/WSGatewayLogin.apiLogin";
+ public static final String GET_NDG_BY_VAT_NUMBER = "/WSAnagrafica.getListaNdg";
+ public static final String CREATE_VISURA = "/WSAnagrafica.createVisura";
+ public static final String GET_VISURA_LIST = "/WSAnagrafica.getVisuraList";
+ public static final String GET_APPOINTMENT_TEMPLATE = "/WSCrmConsulenza.getAppuntamentoTemplate?idAppuntamentoTemplate=7";
+ public static final String CREATE_APPOINTMENT_FROM_TEMPLATE = "/WSCrmConsulenza.createAppointmentFromTemplate";
+ public static final String UPLOAD_APOOINTMENT_DOCUMENT = "/WSDocumentDetail.createStream";
+
+ //get ndg number
+ public static final int TARGET_PAGE_SIZE = 1;
+ public static final int RECORD_PER_PAGE_SIZE = 10;
+
+//create visura request Body constant
+ 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_MODE = "visure";
+ public static final String COD_AGENTE = "UtenzaAPIPortal";
+ public static final boolean IS_FROM_RATING = Boolean.FALSE;
+ public static final boolean IS_ANAGRAFICA_LEGAME = Boolean.FALSE;
+
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java
index d60b0da7..42a9cd41 100644
--- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java
+++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java
@@ -306,5 +306,41 @@ public class GepafinConstant {
public static final String LOGIN_ATTEMPT_ID = "loginAttemptId";
public static final String USER_ACTION_ID = "userActionId";
public static final String ATLEAST_ONE_ID_REQUIRED="atleast.one.id.required";
+
+ //Appointment
+ public static final String NDG_IN_PROGRESS = "IN_PROGRESS";
+ public static final String NDG_AVAILABLE = "ndg.available";
+ public static final String NDG_GENERATION_IS_IN_PROGRESS = "ndg.generation.in.progress";
+ public static final String NDG_GENERATED = "NDG_GENERATED";
+ public static final String NDG_FAILED = "FAILED";
+ public static final String NDG_NOT_FOUND_FOR_APPLICATION = "ndg.not.found.for.this.application.or.invalid";
+ public static final String APPOINTMENT_ALREADY_CREATED = "appointment.already.created";
+ public static final String EXTERNAL_DOCUMENT_UPLOAD_FAILURE_MSG = "document.not.uploaded.to.external.system.please.try.again";
+ public static final String PROVIDE_VALID_APPLICATION_DOC_ID = "provide.valid.application.document.id";
+ public static final String DOCUMENT_UPLOADED_SUCCESSFULLY_TO_EXTERNAL_SYSTEM = "document.uploaded.successfully.to.external.system";
+ public static final String ERROR_UPLOADING_DOCUMENT = "error.in.uploading.document.check.input";
+ public static final String DOCUMENT_ALREADY_UPLOADED = "document.already.uploaded";
+ public static final String NDG_NOT_MATCHED_OR_NOT_FOUND = "ndg.not.found.or.not.matched";
+ public static final String NO_NDG_FOR_ANOTHER_HUB = "ndg.generation.is.only.for.gepafin";
+ public static final String NO_APPOINTMENT_FOR_ANOTHER_HUB = "appointment.creation.is.only.for.gepafin";
+ public static final String NO_DOCUMENT_UPLOAD_FOR_ANOTHER_HUB = "upload.document.is.only.for.gepafin";
+ public static final String APPOINTMENT_CREATED = "appointment.created.successfully";
+ public static final String DATA_STRING = "data";
+ public static final String DOCUMENT_ATTACHMENT_ID_STRING = "documentAttachmentId";
+ public static final String TEMP_FILE_PATH = "/tmp/";
+ public static final String RICHIESTA_CLIENTE_STRING = "richiestaCliente";
+ public static final String ID_STRING = "id";
+ public static final String NULL_STRING = "null";
+ public static final String NDG_STRING = "ndg";
+ public static final String ID_VISURA_STRING = "idVisura";
+ public static final String NDG_FETCH_SUCCESSFULLY = "ndg.fetch.successfully";
+ public static final String AUTH_JWT_SECRET_KEY = "hTa5qe$af/4',BFs";
+ public static final String JWT_ALGO_HEADER = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
+ public static final String HMAC_ALGO = "HmacSHA256";
+ 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 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";
}
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java
index c9c19708..9345b0da 100644
--- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java
+++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java
@@ -105,12 +105,36 @@ public class ApplicationAmendmentRequestDao {
@Autowired
private AssignedApplicationsDao assignedApplicationsDao;
+ @Autowired
+ private ApplicationEvaluationDao applicationEvaluationDao;
+
+ @Autowired
+ private DocumentRepository documentRepository;
+
public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) {
log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId);
ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId);
Long applicationId = applicationEvaluationEntity.getApplicationId();
- ApplicationEntity application = applicationService.validateApplication(applicationId);
+ List evaluationFileRequests=new ArrayList<>();
+ List 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
String callName = application.getCall().getName();
Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null)
@@ -135,11 +159,18 @@ public class ApplicationAmendmentRequestDao {
List forms = applicationFormRepository.findByApplicationId(applicationId);
List allFormFields = new ArrayList<>();
-
+ Map fieldRequestMap = evaluationFileRequests.stream()
+ .collect(Collectors.toMap(FieldRequest::getId, fieldRequest -> fieldRequest));
for (ApplicationFormEntity form : forms) {
String content = form.getForm().getContent();
List> result = filterByName(content, "fileupload");
- allFormFields.addAll(getIdAndLabelFromResult(result));
+ List 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);
@@ -237,6 +268,7 @@ public class ApplicationAmendmentRequestDao {
AmendmentFormField formField = new AmendmentFormField();
formField.setFieldId(amendmentFormFieldRequest.getFieldId());
formField.setFieldValue(null);
+ formField.setLabel(amendmentFormFieldRequest.getLabel());
return formField;
})
.collect(Collectors.toList());
@@ -261,7 +293,7 @@ public class ApplicationAmendmentRequestDao {
Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub());
ProtocolEntity protocolEntity = protocolDao.createProtocolEntity(
applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber,
- userEntity.getHub().getId());
+ userEntity.getHub().getId(),false);
applicationAmendmentRequestEntity.setProtocol(protocolEntity);
ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT);
String evaluationStatusType = applicationEvaluationEntity.getStatus();
@@ -301,6 +333,25 @@ public class ApplicationAmendmentRequestDao {
return applicationAmendment;
}
+ private void setAmendmentDocuments(String amendmentNotes, String amendmentFieldRequest,
+ ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity) {
+ AmendmentDetailsResponseBean amendmentDetails = new AmendmentDetailsResponseBean();
+ if (amendmentFieldRequest != null && !amendmentFieldRequest.trim().isEmpty()) {
+ String[] documentIds = amendmentFieldRequest.split(",");
+ String validDocumentIds = Arrays.stream(documentIds)
+ .map(String::trim)
+ .filter(id -> !id.isEmpty())
+ .collect(Collectors.joining(","));
+
+ amendmentDetails.setAmendmentDocuments(validDocumentIds);
+ }
+ if (amendmentNotes != null && !amendmentNotes.trim().isEmpty()) {
+ amendmentDetails.setAmendmentNotes(amendmentNotes.trim());
+ }
+ amendmentDetails.setValid(null);
+ String amendmentDetailsJson = Utils.convertObjectToString(amendmentDetails);
+ applicationAmendmentRequestEntity.setAmendmentDocument(amendmentDetailsJson);
+ }
public ApplicationAmendmentRequestEntity saveApplicationAmendmentRequestEntity(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity,ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity,VersionActionTypeEnum actionTypeEnum) {
ApplicationAmendmentRequestEntity applicationAmendmentRequest = applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
@@ -316,16 +367,70 @@ public class ApplicationAmendmentRequestDao {
List forms = applicationFormRepository.findByApplicationId(applicationAmendmentRequestEntity.getApplicationId());
Map fieldIdToLabelMap = extractFieldIdToLabelMap(forms);
-
+// List amendmentFieldRequests= new ArrayList<>();
List amendmentFormFields = Utils.convertJsonStringToList(
applicationAmendmentRequestEntity.getFormFields(), AmendmentFormField.class);
Map formFieldEntityMap = getApplicationFormFieldEntityMap(applicationAmendmentRequestEntity, amendmentFormFields);
+ if (applicationAmendmentRequestEntity.getAmendmentDocument() != null) {
+
+// List amendmentDetailsList =
+// Utils.convertJsonStringToList(applicationAmendmentRequestEntity.getAmendmentDocument(),
+// AmendmentDetailsResponseBean.class);
+ AmendmentDetailsResponseBean amendmentDetails = Utils.convertStringToObject(applicationAmendmentRequestEntity.getAmendmentDocument() ,AmendmentDetailsResponseBean.class);
+ if(amendmentDetails!=null) {
+ List documentResponseBeans = new ArrayList<>();
+ if (amendmentDetails.getAmendmentDocuments() != null) {
+ // Extract the comma-separated document IDs as a string
+ String documentIdsString = amendmentDetails.getAmendmentDocuments();
+
+ if (documentIdsString != null && !documentIdsString.trim().isEmpty()) {
+ // Split the comma-separated values and process them
+ List documentIds = Arrays.stream(documentIdsString.split(","))
+ .map(String::trim)
+ .filter(id -> !id.isEmpty())
+ .collect(Collectors.toList());
+
+ documentResponseBeans.addAll(
+ documentIds.stream()
+ .map(id -> {
+ try {
+ return createDocumentResponseBean(id); // Convert to Long
+ } catch (NumberFormatException e) {
+ // Handle invalid document IDs gracefully
+ return null;
+ }
+ })
+ .filter(Objects::nonNull) // Skip null responses
+ .collect(Collectors.toList())
+ );
+ response.setAmendmentNotes(amendmentDetails.getAmendmentNotes());
+ response.setValid(amendmentDetails.getValid());
+ }
+ }
+ response.setAmendmentDocuments(documentResponseBeans);
+ }
+
+
+
+ }
+
processFormFields(amendmentFormFields, fieldIdToLabelMap, formFieldEntityMap, response);
return response;
}
+ public DocumentResponseBean createDocumentResponseBean(String documentId) {
+
+ if (!StringUtils.isEmpty(documentId)) {
+ Optional documentEntity = documentRepository.findByIdAndNotDeleted(Long.valueOf(documentId));
+ if(documentEntity.isPresent()){
+ return applicationEvaluationDao.createDocumentResponseBean(documentEntity.get());
+ }}
+ return null;
+ }
+
+
private ApplicationAmendmentRequestResponse initializeBasicResponse(ApplicationAmendmentRequestEntity entity) {
ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse();
response.setId(entity.getId());
@@ -397,6 +502,7 @@ public class ApplicationAmendmentRequestDao {
responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
return responseBean;
})
.toList();
@@ -510,14 +616,16 @@ public class ApplicationAmendmentRequestDao {
if(updateRequest.getApplicationFormFields() != null) {
updateRequest.getApplicationFormFields().stream().forEach(applicationFormFieldRequest->{
AmendmentFormField amendmentFormField = getAmendmentFormField(amendmentFormFieldMap,applicationFormFieldRequest.getFieldId());
- ApplicationFormFieldEntity applicationFormFieldEntity = getApplicationFormField(applicationFormFieldMap, applicationFormFieldRequest.getFieldId());
- updateApplicationFormField(applicationFormFieldEntity,applicationFormFieldRequest, amendmentFormField);
+// ApplicationFormFieldEntity applicationFormFieldEntity = getApplicationFormField(applicationFormFieldMap, applicationFormFieldRequest.getFieldId());
+// updateApplicationFormField(applicationFormFieldEntity,applicationFormFieldRequest, amendmentFormField);
updateFormField(applicationFormFieldRequest, amendmentFormField);
});
existingApplicationAmendment.setFormFields(Utils.convertListToJsonString(amendmentFormFieldMap.values().stream().toList()));
}
existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
-
+ if(updateRequest.getAmendmentDocuments()!=null && Boolean.FALSE.equals(updateRequest.getAmendmentDocuments().isEmpty())) {
+ setAmendmentDocuments(updateRequest.getAmendmentNotes(),updateRequest.getAmendmentDocuments(), existingApplicationAmendment);
+ }
ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment,oldApplicationAmendmentEntity,VersionActionTypeEnum.UPDATE);
ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment);
log.info("Application Amendment updated successfully: {}", response);
@@ -584,13 +692,13 @@ public class ApplicationAmendmentRequestDao {
String fieldId) {
AmendmentFormField amendmentFormField = amendmentFormFieldMap.get(fieldId);
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;
}
- private void updateFormField(ApplicationFormFieldRequestBean applicationFormFieldRequest,
+ private void updateFormField(AmendmentFormFieldRequest applicationFormFieldRequest,
AmendmentFormField amendmentFormField) {
List requestedDocumentIds = extractIds(applicationFormFieldRequest.getFieldValue());
List existingDocumentIds = extractIds(amendmentFormField.getFieldValue());
@@ -599,7 +707,8 @@ public class ApplicationAmendmentRequestDao {
if (!existingDocumentIds.isEmpty()) {
existingDocumentIds.forEach(this::softDeleteDocument);
amendmentFormField.setFieldValue(null);
- setIsUploadedBy(amendmentFormField);
+ amendmentFormField.setValid(applicationFormFieldRequest.getValid());
+// setIsUploadedBy(amendmentFormField);
}
return;
}
@@ -613,11 +722,12 @@ public class ApplicationAmendmentRequestDao {
if (!newFieldValue.equals(amendmentFormField.getFieldValue())) {
amendmentFormField.setFieldValue(newFieldValue);
- setIsUploadedBy(amendmentFormField);
+ amendmentFormField.setValid(applicationFormFieldRequest.getValid());
+// setIsUploadedBy(amendmentFormField);
}
}
- private List extractIds(Object fieldValue) {
+ public List extractIds(Object fieldValue) {
if (fieldValue instanceof String && !StringUtils.isEmpty((String) fieldValue)) {
return Arrays.stream(((String) fieldValue).split(","))
.map(Long::valueOf)
@@ -628,14 +738,14 @@ public class ApplicationAmendmentRequestDao {
- private void setIsUploadedBy(AmendmentFormField amendmentFormField) {
- if(validator.checkIsBeneficiary()) {
- amendmentFormField.setIsUploadedBy(AmendmentFormField.AmendmentIsUploadedByEnum.BENEFICIARY.getValue());
- }else {
- amendmentFormField.setIsUploadedBy(AmendmentFormField.AmendmentIsUploadedByEnum.PRE_INSTRUCTOR.getValue());
- }
-
- }
+// private void setIsUploadedBy(AmendmentFormField amendmentFormField) {
+// if(validator.checkIsBeneficiary()) {
+// amendmentFormField.setIsUploadedBy(AmendmentFormField.AmendmentIsUploadedByEnum.BENEFICIARY.getValue());
+// }else {
+// amendmentFormField.setIsUploadedBy(AmendmentFormField.AmendmentIsUploadedByEnum.PRE_INSTRUCTOR.getValue());
+// }
+//
+// }
// private void updateApplicationFormFields(ApplicationAmendmentRequestEntity applicationAmendment, ApplicationFormFieldRequestBean updatedFormField) {
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java
index 0feafec8..3b1a11b3 100644
--- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java
+++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java
@@ -836,7 +836,7 @@ public class ApplicationDao {
if (status.equals(ApplicationStatusTypeEnum.SUBMIT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) {
callService.validatePublishedCall(applicationEntity.getCall().getId(), userEntity.getHub().getId());
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.setStatus(ApplicationStatusTypeEnum.SUBMIT.getValue());
applicationEntity.setSubmissionDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
@@ -853,6 +853,9 @@ public class ApplicationDao {
if (status.equals(ApplicationStatusTypeEnum.DRAFT) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.AWAITING.getValue()))) {
applicationEntity.setStatus(status.getValue());
}
+ if(status.equals(ApplicationStatusTypeEnum.ADMISSIBLE) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.APPOINTMENT.getValue()))){
+ applicationEntity.setStatus(status.getValue());
+ }
applicationEntity = applicationRepository.save(applicationEntity);
if (!status.equals(ApplicationStatusTypeEnum.SUBMIT)) {
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java
index 72ba3ad2..7f5e3a56 100644
--- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java
+++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java
@@ -2,7 +2,6 @@ package net.gepafin.tendermanagement.dao;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
@@ -16,18 +15,21 @@ import net.gepafin.tendermanagement.service.*;
import net.gepafin.tendermanagement.util.DateTimeUtil;
import net.gepafin.tendermanagement.util.LoggingUtil;
import net.gepafin.tendermanagement.util.Utils;
+import net.gepafin.tendermanagement.util.Validator;
import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.util.*;
+import java.util.function.Function;
import java.util.stream.Collectors;
import static net.gepafin.tendermanagement.util.Utils.setIfUpdated;
-import static org.apache.commons.lang3.StringUtils.isNumeric;
@Component
public class ApplicationEvaluationDao {
@@ -93,6 +95,15 @@ public class ApplicationEvaluationDao {
@Autowired
private CompanyService companyService;
+ @Autowired
+ private Validator validator;
+
+ @Autowired
+ private DocumentService documentService;
+
+ @Autowired
+ private ApplicationAmendmentRequestDao applicationAmendmentRequestDao;
+
private ApplicationEvaluationEntity convertToEntity(UserEntity user, ApplicationEvaluationRequest req, Long assignedApplciationId) {
ApplicationEvaluationEntity entity = new ApplicationEvaluationEntity();
@@ -112,7 +123,7 @@ public class ApplicationEvaluationDao {
entity.setRemainingDays(30L);
entity.setSuspendedDays(0L);
entity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()));
- entity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(30)));
+ entity.setEndDate(DateTimeUtil.DateServerToUTC(application.getSubmissionDate().plusDays(30)));
entity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue());
return entity;
}
@@ -128,16 +139,103 @@ public class ApplicationEvaluationDao {
List checklistEntities = callTargetAudienceChecklistRepository
.findByCallIdAndLookupDataTypeAndIsDeletedFalse(call.getId(), LookUpDataEntity.LookUpDataTypeEnum.CHECKLIST.getValue());
List applicationFormEntities = applicationFormRepository.findByApplicationId(entity.getApplicationId());
+ setAmendmentDetails(entity,response);
setCriteriaResponses(entity, response, evaluationCriterias);
setChecklistResponses(entity, response, checklistEntities);
setFieldResponses(entity, response, applicationFormEntities);
-
+ List allDocs = prepareEvaluationDocumentBeanList(entity);
+ setEvaluationDocResponse(response, allDocs);
setApplicationDetails(response, entity);
return response;
}
+ private void setAmendmentDetails(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response) {
+ List amendmentRequests=applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(entity.getId());
+ List amendmentDocumentResponseBeans=new ArrayList<>();
+ for(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity:amendmentRequests){
+ AmendmentDocumentResponseBean amendmentDocumentResponseBean=new AmendmentDocumentResponseBean();
+ amendmentDocumentResponseBean.setAmendmentId(applicationAmendmentRequestEntity.getId());
+ String amendmentDocument=applicationAmendmentRequestEntity.getAmendmentDocument();
+ String formField=applicationAmendmentRequestEntity.getFormFields();
+ AmendmentDetailsResponseBean amendmentDetails = Utils.convertStringToObject(amendmentDocument, AmendmentDetailsResponseBean.class);
+ if (amendmentDetails != null) {
+ if (amendmentDetails.getAmendmentDocuments() != null) {
+ List documentResponseBeans = Arrays.stream(amendmentDetails.getAmendmentDocuments().split(","))
+ .map(String::trim)
+ .filter(id -> !id.isEmpty())
+ .map(documentId -> applicationAmendmentRequestDao.createDocumentResponseBean(documentId))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ amendmentDocumentResponseBean.setFileDetail(documentResponseBeans);
+ }
+ amendmentDocumentResponseBean.setFieldId("amend_" + applicationAmendmentRequestEntity.getId());
+ amendmentDocumentResponseBean.setLabel(amendmentDetails.getAmendmentNotes());
+ amendmentDocumentResponseBean.setValid(amendmentDetails.getValid());
+ amendmentDocumentResponseBeans.add(amendmentDocumentResponseBean);
+ }
+ List amendmentFormFields = Utils.convertJsonStringToList(formField, AmendmentFormField.class);
+ if (amendmentFormFields != null) {
+ for (AmendmentFormField amendmentFormField : amendmentFormFields) {
+ // Skip fields with null or empty fieldValue
+ if (StringUtils.isEmpty(amendmentFormField.getFieldValue())) {
+ continue;
+ }
+
+ AmendmentDocumentResponseBean formFieldResponseBean = new AmendmentDocumentResponseBean();
+ formFieldResponseBean.setAmendmentId(applicationAmendmentRequestEntity.getId());
+ formFieldResponseBean.setFieldId(amendmentFormField.getFieldId());
+ formFieldResponseBean.setLabel(amendmentFormField.getLabel());
+ formFieldResponseBean.setValid(amendmentFormField.getValid());
+
+ List fileIds = applicationAmendmentRequestDao.extractIds(amendmentFormField.getFieldValue());
+ List documentResponseBeans = fileIds.stream()
+ .map(fileId -> createDocumentResponseBean(documentService.validateDocument(fileId)))
+ .collect(Collectors.toList());
+
+ formFieldResponseBean.setFileDetail(documentResponseBeans);
+ amendmentDocumentResponseBeans.add(formFieldResponseBean);
+ }
+ }
+ }
+
+ response.setAmendmentDetails(amendmentDocumentResponseBeans);
+ }
+
+ private void setEvaluationDocResponse(ApplicationEvaluationResponse response, List docRequest) {
+ List evaluationDocResponses = new ArrayList<>();
+
+ for (EvaluationDocumentRequest doc : docRequest) {
+ EvaluationDocumentResponse evaluationDocResponse = new EvaluationDocumentResponse();
+ if (doc.getFileValue() != null) {
+ Long fileId = Long.valueOf(doc.getFileValue().toString());
+ documentRepository.findByIdAndNotDeleted(fileId).ifPresent(documentEntity -> {
+ DocumentResponseBean documentResponseBean = new DocumentResponseBean();
+ documentResponseBean.setId(documentEntity.getId());
+ documentResponseBean.setName(documentEntity.getFileName());
+ documentResponseBean.setType(DocumentTypeEnum.valueOf(documentEntity.getType()));
+ documentResponseBean.setSource(DocumentSourceTypeEnum.valueOf(documentEntity.getSource()));
+ documentResponseBean.setSourceId(documentEntity.getSourceId());
+ documentResponseBean.setFilePath(documentEntity.getFilePath());
+ documentResponseBean.setCreatedDate(documentEntity.getCreatedDate());
+ documentResponseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ documentResponseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
+ evaluationDocResponse.setFileValue(List.of(documentResponseBean));
+ evaluationDocResponse.setNameValue(doc.getNameValue());
+ evaluationDocResponse.setValid(doc.getValid());
+ evaluationDocResponse.setFieldId(doc.getFieldId());
+ });
+ }
+ if (evaluationDocResponse.getFileValue() == null) {
+ continue;
+ }
+ evaluationDocResponses.add(evaluationDocResponse);
+ }
+ response.setEvaluationDocument(evaluationDocResponses);
+ }
+
private void populateBasicDetails(ApplicationEvaluationEntity entity, ApplicationEvaluationResponse response) {
response.setId(entity.getId());
@@ -286,6 +384,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean);
});
}
@@ -399,6 +498,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean);
allDocumentsDeleted[0] = false;
}
@@ -448,6 +548,8 @@ public class ApplicationEvaluationDao {
String beneficiary = String.join(" ", firstName, lastName).trim();
response.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(application.getStatus()));
response.setBeneficiary(beneficiary);
+ response.setNdg(application.getNdg() != null ? application.getNdg() : null);
+ response.setAppointmentId(application.getAppointmentId() != null ? application.getAppointmentId() : null);
response.setSubmissionDate(application.getSubmissionDate());
response.setMinScore(call.getThreshold() != null ? call.getThreshold() : null);
response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null);
@@ -481,9 +583,15 @@ public class ApplicationEvaluationDao {
if (existingEntityOptional.isPresent()) {
entity = existingEntityOptional.get();
oldApplicationEvaluation = Utils.getClonedEntityForData(entity);
- entity.setCriteria(Utils.convertObjectToJson(filterNonNullCriteria(processCriteria(entity, req))));
- entity.setChecklist(Utils.convertObjectToJson(filterNonNullChecklist(processChecklist(entity, req))));
- entity.setFile(Utils.convertObjectToJson(filterNonNullFields(processField(entity, req))));
+ if(req.getCriteria()!=null) {
+ entity.setCriteria(Utils.convertObjectToJson(processCriteria(entity, req)));
+ }
+ if(req.getChecklist()!=null) {
+ entity.setChecklist(Utils.convertObjectToJson(processChecklist(entity, req)));
+ }
+ if(req.getFiles()!=null) {
+ entity.setFile(Utils.convertObjectToJson(processField(entity, req)));
+ }
entity.setIsDeleted(false);
setIfUpdated(entity::getNote, entity::setNote, req.getNote());
setIfUpdated(entity::getMotivation, entity::setMotivation, req.getMotivation());
@@ -493,6 +601,18 @@ public class ApplicationEvaluationDao {
actionType = VersionActionTypeEnum.INSERT;
}
ApplicationStatusForEvaluation status = req.getApplicationStatus();
+ // Fetch all amendment request entities associated with the evaluation ID
+ List applicationAmendmentRequestEntities =
+ applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(entity.getId());
+ if(req.getEvaluationDocument()!=null) {
+ updateApplicationEvaluation(assignedApplicationId, req.getEvaluationDocument());
+ }
+// Fetch amendment details from the request
+ if(req.getAmendmentDetails()!=null) {
+ List amendmentDetailsRequests = req.getAmendmentDetails();
+
+ updateAmendmentDocumentsAndFormFields(applicationAmendmentRequestEntities, amendmentDetailsRequests);
+}
ApplicationEvaluationEntity savedEntity = applicationEvaluationRepository.save(entity);
@@ -508,22 +628,210 @@ public class ApplicationEvaluationDao {
}
}
+ private void updateAmendmentDocumentsAndFormFields(List applicationAmendmentRequestEntities, List amendmentFormFields) {
+ // Iterate through amendment request entities
- private List filterNonNullChecklist(List checklistRequests) {
+//
+ Map> amendmentFormFieldsMap = amendmentFormFields.stream().collect(Collectors.groupingBy(AmendmentDetailsRequest::getAmendmentId,HashMap::new,Collectors.toCollection(ArrayList::new)));
+// amendmentFormFields.forEach(data->{
+// ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = applicationAmendmentRequestMap.get(data.getAmendmentId());
+// if (data.getFieldId().contains("amend_")){
+// updateAmendmentDocument(applicationAmendmentRequestEntity, data);
+// }
+// });
+ applicationAmendmentRequestEntities.forEach(applicationAmendmentRequestEntity->{
+ updateAmendment(applicationAmendmentRequestEntity, amendmentFormFieldsMap.get(applicationAmendmentRequestEntity.getId()));
+ });
+ applicationAmendmentRequestRepository.saveAll(applicationAmendmentRequestEntities);
- return checklistRequests.stream().filter(request -> request.getValid() != null).collect(Collectors.toList());
+
+// for (ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity : applicationAmendmentRequestEntities) {
+// // Process form fields if present
+// if (applicationAmendmentRequestEntity.getFormFields() != null) {
+// // Parse existing form fields from JSON
+// List existingFormFields =
+// Utils.convertJsonStringToList(applicationAmendmentRequestEntity.getFormFields(), AmendmentFormFieldRequest.class);
+//
+// // Prepare a new list to hold updated form fields
+// List updatedFormFields = new ArrayList<>();
+//
+// // Map amendment details for quick lookup by amendment ID
+// Map amendmentDetailsMap = amendmentFormFields.stream()
+// .filter(details -> applicationAmendmentRequestEntity.getId().equals(details.getAmendmentId()))
+// .filter(details -> details.getFieldValue() != null) // Null check for getFormFieldDocuments
+// .collect(Collectors.toMap(
+// AmendmentDetailsRequest::getAmendmentId,
+// AmendmentDetailsRequest::getFieldValue
+// ));
+// // Get corresponding amendment documents for the current entity
+// List amendmentDocuments = (List) amendmentDetailsMap.get(applicationAmendmentRequestEntity.getId());
+// if (amendmentDocuments != null) {
+// // Update existing form fields with new values
+// for (AmendmentFormFieldRequest existingField : existingFormFields) {
+// for (AmendmentFormFieldRequest newField : amendmentDocuments) {
+// if (existingField.getFieldId().equals(newField.getFieldId())) {
+// // Update fields if there are changes
+// Utils.setIfUpdated(existingField::getValid, existingField::setValid, newField.getValid());
+// Utils.setIfUpdated(existingField::getFieldValue, existingField::setFieldValue, newField.getFieldValue());
+//
+// updatedFormFields.add(existingField);
+// break; // Move to the next existing field
+// }
+// }
+// }
+//
+// // Convert updated form fields back to JSON and save to the database
+// applicationAmendmentRequestEntity.setFormFields(Utils.convertListToJsonString(updatedFormFields));
+// applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
+// }
+// }
+//
+// // Process amendment documents if present
+// if (applicationAmendmentRequestEntity.getAmendmentDocument() != null) {
+// String existingDocumentIds = applicationAmendmentRequestEntity.getAmendmentDocument();
+//
+// // Split comma-separated document IDs into a list
+// List existingDocumentIdList = Arrays.stream(existingDocumentIds.split(","))
+// .map(String::trim)
+// .filter(id -> !id.isEmpty())
+// .collect(Collectors.toList());
+//
+// List updatedDocumentIdList = new ArrayList<>();
+// Map amendmentDetailsMap = amendmentFormFields.stream()
+// .filter(details -> applicationAmendmentRequestEntity.getId().equals(details.getAmendmentId()))
+// .collect(Collectors.toMap(
+// AmendmentDetailsRequest::getAmendmentId,
+// AmendmentDetailsRequest::getFieldValue
+// ));
+//
+// String amendmentDocumentIds = (String) amendmentDetailsMap.get(applicationAmendmentRequestEntity.getId());
+// if (amendmentDocumentIds != null) {
+// // Split and validate new document IDs
+// List newDocumentIdList = Arrays.stream(amendmentDocumentIds.split(","))
+// .map(String::trim)
+// .filter(id -> !id.isEmpty())
+// .collect(Collectors.toList());
+//
+// for (String existingId : existingDocumentIdList) {
+// for (String newId : newDocumentIdList) {
+// if (existingId.equals(newId)) {
+// Optional documentEntity = documentRepository.findByIdAndNotDeleted(Long.valueOf(newId));
+// if(documentEntity.isPresent()) {
+// updatedDocumentIdList.add(newId);
+// break;
+// }
+// }
+// }
+// }
+//
+// // Add any new IDs not in the existing list
+// for (String newId : newDocumentIdList) {
+// if (!existingDocumentIdList.contains(newId)) {
+// Optional documentEntity = documentRepository.findByIdAndNotDeleted(Long.valueOf(newId));
+// if(documentEntity.isPresent()) {
+// updatedDocumentIdList.add(newId);
+// }
+// }
+// }
+// String updatedDocumentIds = String.join(",", updatedDocumentIdList);
+//
+// // Create the AmendmentDetailsResponseBean for structured data
+// AmendmentDetailsResponseBean amendmentDetails = new AmendmentDetailsResponseBean();
+// amendmentDetails.setAmendmentDocuments(updatedDocumentIds);
+// AmendmentDetailsRequest amendmentDetailsRequest = amendmentFormFields.stream()
+// .filter(details -> applicationAmendmentRequestEntity.getId().equals(details.getAmendmentId()))
+// .findFirst()
+// .orElse(null);
+//
+// if (amendmentDetailsRequest != null) {
+// amendmentDetails.setValid(amendmentDetailsRequest.getValid());
+// } else {
+// amendmentDetails.setValid(false);
+// }
+// String amendmentDetailsJson = Utils.convertListToJsonString(Collections.singletonList(amendmentDetails));
+// applicationAmendmentRequestEntity.setAmendmentDocument(amendmentDetailsJson);
+// applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
+// }
+// }
+// }
}
- private List filterNonNullCriteria(List criteriaRequests) {
+ private void updateAmendment(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity, List amendmentDetailsRequestList) {
+ if (CollectionUtils.isEmpty(amendmentDetailsRequestList)) {
+ return;
+ }
+ Map formFieldsMap = null;
+ List formFieldList = Utils.convertJsonStringToList(applicationAmendmentRequestEntity.getFormFields(), AmendmentFormField.class);
+ if(Boolean.FALSE.equals(CollectionUtils.isEmpty(formFieldList))){
+ formFieldsMap = formFieldList.stream().collect(Collectors.toMap(AmendmentFormField::getFieldId, Function.identity()));
+ }
+ updateAmendmentData(applicationAmendmentRequestEntity, amendmentDetailsRequestList, formFieldsMap);
- return criteriaRequests.stream().filter(request -> request.getScore() != null && request.getValid() != null).collect(Collectors.toList());
}
- private List filterNonNullFields(List fieldRequests) {
-
- return fieldRequests.stream().filter(request -> request.getValid() != null).collect(Collectors.toList());
+ private static void updateAmendmentData(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity, List amendmentDetailsRequestList, Map formFieldsMap) {
+ amendmentDetailsRequestList.forEach(amendmentDetailsRequest -> {
+ if (amendmentDetailsRequest.getFieldId().contains("amend_")) {
+ AmendmentDetailsResponseBean amendmentDetails = Utils.convertStringToObject(applicationAmendmentRequestEntity.getAmendmentDocument(), AmendmentDetailsResponseBean.class);
+ if(amendmentDetails!=null) {
+ amendmentDetails.setValid(amendmentDetailsRequest.getValid());
+ applicationAmendmentRequestEntity.setAmendmentDocument(Utils.convertObjectToString(amendmentDetails));
+ }
+ } else if(Boolean.FALSE.equals(CollectionUtils.isEmpty(formFieldsMap))){
+ AmendmentFormField amendmentFormField = formFieldsMap.get(amendmentDetailsRequest.getFieldId());
+ amendmentFormField.setValid(amendmentDetailsRequest.getValid());
+ }
+ });
+ applicationAmendmentRequestEntity.setFormFields(Utils.convertListToJsonString(formFieldsMap.values().stream().toList()));
}
+
+// private void updateAmendmentDocuments(List applicationAmendmentRequestEntities, List amendmentFormFields) {
+// for (ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity : applicationAmendmentRequestEntities) {
+// // Skip if there are no amendment documents
+// if (applicationAmendmentRequestEntity.getAmendmentDocument() == null) {
+// continue;
+// }
+//
+// // Parse existing amendment fields from JSON
+// List existingAmendmentFields =
+// Utils.convertJsonStringToList(applicationAmendmentRequestEntity.getAmendmentDocument(), AmendmentFieldRequest.class);
+//
+// // Prepare a new list to hold updated amendment fields
+// List updatedAmendmentFields = new ArrayList<>();
+//
+// // Map amendment details for quick lookup by amendment ID
+// Map> amendmentDetailsMap = amendmentFormFields.stream()
+// .filter(details -> applicationAmendmentRequestEntity.getId().equals(details.getAmendmentId()))
+// .collect(Collectors.toMap(AmendmentDetailsRequest::getAmendmentId, AmendmentDetailsRequest::getAmendmentDocuments));
+//
+// // Get corresponding amendment documents for the current entity
+// List amendmentDocuments = amendmentDetailsMap.get(applicationAmendmentRequestEntity.getId());
+// if (amendmentDocuments == null) {
+// continue;
+// }
+//
+// // Update existing amendment fields with new values
+// for (AmendmentFieldRequest existingField : existingAmendmentFields) {
+// for (AmendmentFieldRequest newField : amendmentDocuments) {
+// if (existingField.getFieldId().equals(newField.getFieldId())) {
+// // Update fields if there are changes
+// Utils.setIfUpdated(existingField::getIsValid, existingField::setIsValid, newField.getIsValid());
+// Utils.setIfUpdated(existingField::getFileValue, existingField::setFileValue, newField.getFileValue());
+// Utils.setIfUpdated(existingField::getNameValue, existingField::setNameValue, newField.getNameValue());
+//
+// updatedAmendmentFields.add(existingField);
+// break; // Move to the next existing field
+// }
+// }
+// }
+//
+// // Convert updated fields back to JSON and save to the database
+// applicationAmendmentRequestEntity.setAmendmentDocument(Utils.convertListToJsonString(updatedAmendmentFields));
+// applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity);
+// }
+// }
+
private List processCriteria(ApplicationEvaluationEntity entity, ApplicationEvaluationRequest req) {
List incomingCriteriaList = Optional.ofNullable(req.getCriteria()).orElse(new ArrayList<>());
@@ -643,11 +951,52 @@ public class ApplicationEvaluationDao {
return entityOptional.get();
}
+ public void validatePreinstructor(HttpServletRequest request,Long applicationId,Long assignedApplicationId){
+ if (applicationId == null && assignedApplicationId == null) {
+ throw new CustomValidationException(
+ Status.BAD_REQUEST,
+ Translator.toLocale(GepafinConstant.EITHER_APPLICATION_OR_ASSIGNED_APPLICATION_ID_REQUIRED_MSG)
+ );
+ }
+ Optional assignedApplicationsOptional =
+ assignedApplicationsRepository.findByApplicationIdOrIdAndIsDeletedFalse(applicationId,assignedApplicationId);
- public ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(UserEntity user, Long applicationId, Long assignedApplicationId) {
+ if (assignedApplicationId != null) {
+ assignedApplicationsOptional = assignedApplicationsOptional.filter(a -> a.getId().equals(assignedApplicationId));
+ }
+ AssignedApplicationsEntity assignedApplications = assignedApplicationsOptional
+ .orElseThrow(() -> new CustomValidationException(
+ Status.BAD_REQUEST,
+ Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_WITH_ID_MSG)
+ ));
+ if (applicationId == null) {
+ applicationId = assignedApplications.getApplication().getId();
+ }
+ validator.validatePreInstructor(request, assignedApplications.getUserId());
+ }
+ public ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(HttpServletRequest request, UserEntity user, Long applicationID, Long assignedApplicationID) {
+ Long applicationId;
+ Long assignedApplicationId;
+ validatePreinstructor(request, applicationID, assignedApplicationID);
+ if (applicationID == null && assignedApplicationID != null) {
+ assignedApplicationId = assignedApplicationID;
+ Optional assignedApplicationsOptional =
+ assignedApplicationsRepository.findByIdAndIsDeletedFalse(assignedApplicationId);
+
+ applicationId = assignedApplicationsOptional.map(a -> a.getApplication().getId()).orElse(null);
+ } else {
+ applicationId = applicationID;
+ if (assignedApplicationID == null && applicationID != null) {
+ Optional assignedApplicationsOptional =
+ assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId);
+
+ assignedApplicationId = assignedApplicationsOptional.map(AssignedApplicationsEntity::getId).orElse(null);
+ } else {
+ assignedApplicationId = assignedApplicationID;
+ }
+ }
applicationService.validateApplication(applicationId);
-
Optional entityOptional;
if (applicationId != null && assignedApplicationId != null) {
@@ -659,11 +1008,19 @@ public class ApplicationEvaluationDao {
} else {
entityOptional = applicationEvaluationRepository.findFirstByIsDeletedFalseOrderByCreatedDateDesc();
}
- return entityOptional.map(this::convertToResponse)
+ return entityOptional.map(this::convertToResponse)
.orElseGet(() -> {
return getEvaluationResponseByApplicationid(user, applicationId, assignedApplicationId);
});
}
+ private List prepareEvaluationDocumentBeanList(ApplicationEvaluationEntity entity) {
+ List docRequest = new ArrayList<>();
+
+ if (entity != null && entity.getEvaluationDocument() != null) {
+ docRequest = Utils.convertJsonToList(entity.getEvaluationDocument(), new TypeReference>() {});
+ }
+ return docRequest;
+ }
public ApplicationEvaluationResponse getEvaluationResponseByApplicationid(UserEntity user, Long applicationId, Long assignedApplicationId) {
@@ -761,7 +1118,7 @@ public class ApplicationEvaluationDao {
if (!mappedFieldMap.containsKey(formFieldId)) {
// CriteriaMappedField mappedField = new CriteriaMappedField();
CriteriaMappedField mappedField = populateMappedField(formFieldId, criteriaFormField, applicationForm, applicationId);
- if(mappedField != null) {
+ if(mappedField != null) {
mappedFieldMap.put(formFieldId, mappedField);
}
}
@@ -890,7 +1247,7 @@ public class ApplicationEvaluationDao {
}
- private DocumentResponseBean createDocumentResponseBean(DocumentEntity documentEntity) {
+ public DocumentResponseBean createDocumentResponseBean(DocumentEntity documentEntity) {
DocumentResponseBean responseBean = new DocumentResponseBean();
responseBean.setId(documentEntity.getId());
responseBean.setName(documentEntity.getFileName());
@@ -900,6 +1257,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
return responseBean;
}
@@ -972,6 +1330,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean);
});
}
@@ -1002,6 +1361,8 @@ public class ApplicationEvaluationDao {
String beneficiary = String.join(" ", firstName, lastName).trim();
response.setBeneficiary(beneficiary);
response.setSubmissionDate(application.getSubmissionDate());
+ response.setNdg(application.getNdg() != null ? application.getNdg() : null);
+ response.setAppointmentId(application.getAppointmentId() != null ? application.getAppointmentId() : null);
response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null);
response.setProtocolNumber((application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : null);
if (assignedApplications != null) {
@@ -1220,6 +1581,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
return responseBean;
}
@@ -1346,6 +1708,7 @@ public class ApplicationEvaluationDao {
responseBean.setFilePath(documentEntity.getFilePath());
responseBean.setCreatedDate(documentEntity.getCreatedDate());
responseBean.setUpdatedDate(documentEntity.getUpdatedDate());
+ responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId());
documentResponseBeans.add(responseBean);
});
}
@@ -1403,6 +1766,10 @@ public class ApplicationEvaluationDao {
ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(existingEntity);
AssignedApplicationsEntity oldAssignedApplication = Utils.getClonedEntityForData(assignedApplicationsEntity);
+ List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(existingEntity.getId(),ApplicationAmendmentRequestEnum.AWAITING.getValue());
+ if(amendmentRequest !=null && Boolean.FALSE.equals(amendmentRequest.isEmpty())){
+ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_CANNOT_APPROVED_OR_REJECTED));
+ }
String statusType = application.getStatus();
if (application.getStatus().equals(ApplicationStatusTypeEnum.APPROVED.getValue()) || application.getStatus().equals(ApplicationStatusTypeEnum.REJECTED.getValue())) {
existingEntity.setStatus(ApplicationEvaluationStatusTypeEnum.CLOSE.getValue());
@@ -1421,11 +1788,6 @@ public class ApplicationEvaluationDao {
}
- List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(existingEntity.getId(),ApplicationAmendmentRequestEnum.AWAITING.getValue());
- if(amendmentRequest !=null && Boolean.FALSE.equals(amendmentRequest.isEmpty())){
- throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_CANNOT_APPROVED_OR_REJECTED));
- }
-
if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.APPROVED.getValue())))) {
emailNotificationDao.sendAdmissibilityNotificationEmailForApprovedApplication(application);
}
@@ -1443,5 +1805,33 @@ public class ApplicationEvaluationDao {
.orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND,
Translator.toLocale(GepafinConstant.APPLICATION_EVALUATION_NOT_FOUND)));
}
+
+ public ApplicationEvaluationResponse updateApplicationEvaluation(
+ Long assignedApplicationId,
+ List docRequest) {
+ Optional entityOptional=applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse(assignedApplicationId);
+ ApplicationEvaluationEntity applicationEvaluationEntity =null;
+ ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(entityOptional.get());
+ applicationEvaluationEntity = entityOptional.get();
+
+ if (docRequest != null) {
+ List existingDocs = new ArrayList<>();
+
+ for (EvaluationDocumentRequest doc : docRequest) {
+ if (doc.getFileValue() != null) {
+ Long fileId = Long.valueOf(doc.getFileValue());
+ documentService.validateDocument(fileId);
+ existingDocs.add(doc);
+ }
+ }
+ String updatedEvaluationDocJson = Utils.convertObjectToJson(existingDocs);
+ applicationEvaluationEntity.setEvaluationDocument(updatedEvaluationDocJson);
+ }
+ ApplicationEvaluationEntity savedEntity = applicationEvaluationRepository.save(applicationEvaluationEntity);
+
+ /** This code is responsible for adding a version history log for the "Upload Document in Application Evaluation" operation. **/
+ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluation).newData(savedEntity).build());
+ return convertToResponse(savedEntity);
+ }
}
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java
new file mode 100644
index 00000000..f1fb2b8f
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java
@@ -0,0 +1,904 @@
+package net.gepafin.tendermanagement.dao;
+
+import com.amazonaws.services.s3.AmazonS3Client;
+import com.amazonaws.services.s3.model.GetObjectRequest;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import feign.FeignException;
+import io.jsonwebtoken.Claims;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+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.ApplicationEntity;
+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.VersionActionTypeEnum;
+import net.gepafin.tendermanagement.model.request.AppointmentCreationRequest;
+import net.gepafin.tendermanagement.model.request.AppointmentNdgRequest;
+import net.gepafin.tendermanagement.model.request.AppointmentVisuraListRequest;
+import net.gepafin.tendermanagement.model.request.AppointmentVisuraRequest;
+import net.gepafin.tendermanagement.model.request.CreateAppointmentRequest;
+import net.gepafin.tendermanagement.model.request.UploadDocToExternalSystemRequest;
+import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
+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.service.ApplicationService;
+import net.gepafin.tendermanagement.service.CompanyService;
+import net.gepafin.tendermanagement.service.feignClient.AppointmentApiService;
+import net.gepafin.tendermanagement.util.LoggingUtil;
+import net.gepafin.tendermanagement.util.Utils;
+import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
+import net.gepafin.tendermanagement.web.rest.api.errors.Status;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+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.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Component
+public class AppointmentDao {
+
+ @Value("${appointment.portal.user}")
+ private String user;
+
+ @Value("${appointment.portal.password}")
+ private String password;
+
+ @Value("${appointment.portal.source}")
+ private String source;
+
+ @Value("${appointment.portal.context}")
+ private String context;
+
+ @Value("${default.hub.uuid}")
+ private String defaultHubUuid;
+
+ @Value("${aws.s3.url}")
+ private String s3Url;
+
+ @Value("${aws.s3.bucket.name}")
+ private String OLD_BUCKET;
+
+ @Value("${flagDaFirmare}")
+ private Boolean flagDaFirmare;
+
+ @Autowired
+ private HubRepository hubRepository;
+
+ @Autowired
+ private AppointmentApiService appointmentApiService;
+
+ @Autowired
+ private ApplicationService applicationService;
+
+ @Autowired
+ private CompanyService companyService;
+
+ @Autowired
+ private ApplicationRepository applicationRepository;
+
+ @Autowired
+ private CompanyRepository companyRepository;
+
+ @Autowired
+ private DocumentDao documentDao;
+
+ @Autowired
+ private AmazonS3Client s3Client;
+
+ @Autowired
+ private DocumentRepository documentRepository;
+
+ @Autowired
+ private HttpServletRequest request;
+
+ @Autowired
+ private LoggingUtil loggingUtil;
+
+ @Autowired
+ private TokenProvider tokenProvider;
+
+ private final Map executorMap = new ConcurrentHashMap<>();
+
+ private final ConcurrentHashMap threadForDocumentMap = new ConcurrentHashMap<>();
+
+ private static final ThreadLocal threadLocalHubId = new ThreadLocal<>();
+
+ 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 {
+ // Authenticate and fetch token if required
+ if (hub.getAppointmentAuthTokenId() == null || hub.getAreaCode() == null) {
+ authenticateAndSaveToken(hub);
+ }
+
+ String authorizationToken = getBearerToken(hub);
+
+ // Try retrieving NDG by VAT number
+ AppointmentLoginResponse ndgResponse = retrieveNdgByVatNumber(company.getVatNumber(), authorizationToken, hub, application);
+ if (isNdgValid(ndgResponse.getNdg())) {
+ saveNdgAndIdVisura(application, company, ndgResponse.getNdg(), null);
+ log.info("NDG successfully generated for applicationId: {}", applicationId);
+ } else {
+ // If NDG isn't immediately available, start polling
+ handleNdgPolling(application, company, hub, authorizationToken);
+ }
+ } catch (Exception e) {
+ log.error("Error during NDG generation for applicationId: {}", applicationId, e);
+ }
+ }
+
+ private void handleNdgPolling(ApplicationEntity application, CompanyEntity company, HubEntity hub, String authorizationToken) {
+
+ try {
+ log.info("Starting NDG polling for applicationId: {}", application.getId());
+ long startTime = System.currentTimeMillis();
+
+ while (true) {
+ 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());
+ }
+ }
+
+ private static String getBearerToken(HubEntity hub) {
+
+ return "Bearer " + hub.getAppointmentAuthTokenId();
+ }
+
+ private boolean isNdgValid(String ndg) {
+
+ return ndg != null && !ndg.isEmpty();
+ }
+
+ private void saveNdgAndIdVisura(ApplicationEntity application, CompanyEntity company, String ndg, String idVisura) {
+
+ //cloned for old application and company data
+ // ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
+ // CompanyEntity oldCompanyData = Utils.getClonedEntityForData(company);
+
+ application.setNdg(ndg);
+ application.setIdVisura(idVisura);
+ application.setNdgStatus(GepafinConstant.NDG_GENERATED);
+ application.setStatus(ApplicationStatusTypeEnum.NDG.getValue());
+ company.setNdg(ndg);
+ companyRepository.save(company);
+ applicationRepository.save(application);
+
+ // /** 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());
+
+ log.info("NDG saved for applicationId: {}, {}", application.getId(), application.getNdg());
+ }
+
+ private String getVisuraList(String idVisura, String authorizationToken, ApplicationEntity application, HubEntity hub) {
+
+ AppointmentVisuraListRequest visuraListRequest = new AppointmentVisuraListRequest();
+ AppointmentVisuraListRequest.VisuraFilter filter = new AppointmentVisuraListRequest.VisuraFilter();
+ filter.setIdVisura(idVisura);
+ visuraListRequest.setFilter(filter);
+
+ try {
+ String requestJson = Utils.convertObjectToJson(visuraListRequest);
+ ResponseEntity response = appointmentApiService.getVisuraList(requestJson, authorizationToken);
+ return Utils.convertObjectToJson(response.getBody());
+ } catch (FeignException.Forbidden forbiddenException) {
+ log.error("403 Forbidden received while getting visuraList for Ndg code. Regenerating token...");
+ // Regenerate the token and retry
+ String newAuthorizationToken = regenerateTokenAndSave(hub);
+ return getVisuraList(idVisura, newAuthorizationToken, application, hub);
+ } catch (Exception e) {
+ log.error("Failed to fetch Ndg code: {}", e.getMessage(), e);
+ throw new RuntimeException("Error fetching Ndg List", e);
+ }
+ }
+
+ private HubEntity authenticateAndSaveToken(HubEntity hub) {
+
+ // HubEntity oldHubData = Utils.getClonedEntityForData(hub);
+ try {
+ //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();
+ log.info("Got the auth for login to odessa {}", authJwtToken);
+ hub.setAuthToken(authJwtToken);
+ hubRepository.save(hub);
+
+ // /** 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());
+
+ // Prepare the request body (adjust if necessary for login API)
+ Map body = Collections.emptyMap();
+ // Perform login API call
+ ResponseEntity responseLogin = appointmentApiService.loginWithOdessa(authJwtToken, source, context, user, password, body);
+
+ // Handle successful login
+ if (responseLogin.getStatusCode() == HttpStatus.OK) {
+ log.info("Login successful to odessa. Parsing response.");
+ String loginResponseJson = Utils.convertObjectToJson(responseLogin.getBody());
+ AppointmentLoginResponse parsedResponse = parseLoginResponse(loginResponseJson);
+
+ // Validate and save token
+ if (parsedResponse.getTokenId() != null) {
+ hub.setAppointmentAuthTokenId(parsedResponse.getTokenId());
+ hub.setAreaCode(parsedResponse.getAreaCode());
+ 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"
+ // * operation. **/
+ // loggingUtil.addVersionHistory(
+ // VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldHubData).newData(hub)
+ // .build());
+
+ log.info("Saved new authToken and areaCode for Hub.");
+ return hub;
+ } else {
+ throw new RuntimeException("Login response is missing a valid tokenId for login to odessa system, please try again.");
+ }
+ }
+ // Handle non-OK response
+ throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.ERROR_IN_GENERATING_NDG_TRY_AGAIN));
+ } catch (Exception e) {
+ log.error("Failed to authenticate user on Odessa : {}", e.getMessage(), e);
+ throw new RuntimeException("Authentication failed on Odessa. try again", e);
+ }
+ }
+
+ private AppointmentLoginResponse retrieveNdgByVatNumber(String vatNumber, String authorizationToken, HubEntity hub, ApplicationEntity application) {
+
+ try {
+ // Prepare the NDG request
+ AppointmentNdgRequest ndgRequest = getAppointmentNdgRequest(vatNumber);
+ // Call the API to retrieve NDG
+ ResponseEntity response = appointmentApiService.getNdgByVatNumber(ndgRequest, authorizationToken);
+ String responseJson = Utils.convertObjectToJson(response.getBody());
+ // Parse and return the NDG response
+ return parseNdgResponse(responseJson);
+ } catch (FeignException.Forbidden forbiddenException) {
+ logForbiddenError();
+ // Regenerate the token and retry
+ String newAuthorizationToken = regenerateTokenAndSave(hub);
+ return retrieveNdgByVatNumber(vatNumber, newAuthorizationToken, hub, application);
+ } catch (Exception e) {
+ log.error("Failed to retrieve NDG by VAT number: {}", e.getMessage(), e);
+ throw new RuntimeException("NDG retrieval failed.", e);
+ }
+ }
+
+ private String regenerateTokenAndSave(HubEntity hub) {
+
+ try {
+ hub = authenticateAndSaveToken(hub);
+ return "Bearer " + hub.getAppointmentAuthTokenId();
+ } catch (Exception e) {
+ log.error("Failed to regenerate token from Odessa: {}", e.getMessage());
+ throw new RuntimeException("Token regeneration failed from Odessa.", e);
+ }
+ }
+
+ private AppointmentLoginResponse createVisura(CompanyEntity company, String authorizationToken, HubEntity hub) {
+
+ try {
+ String visuraRequest = getAppointmentVisuraRequest(company, hub.getAreaCode());
+ ResponseEntity response = appointmentApiService.createVisura(visuraRequest, authorizationToken);
+ String responseJson = Utils.convertObjectToJson(response.getBody());
+ return parseVisuraResponse(responseJson);
+ } catch (FeignException.Forbidden forbiddenException) {
+ logForbiddenError();
+ // Regenerate the token and retry
+ String newAuthorizationToken = regenerateTokenAndSave(hub);
+ return createVisura(company, newAuthorizationToken, hub);
+ } catch (Exception e) {
+ log.error("Failed to create Visura for Ndg : {}", e.getMessage());
+ throw new RuntimeException("Visura creation failed for Ndg.", e);
+ }
+ }
+
+ private static void logForbiddenError() {
+
+ log.error("403 Forbidden received while retrieving NDG. Regenerating token...");
+ }
+
+ private static AppointmentNdgRequest getAppointmentNdgRequest(String vatNumber) {
+
+ AppointmentNdgRequest request = new AppointmentNdgRequest();
+ AppointmentNdgRequest.Filter filter = new AppointmentNdgRequest.Filter();
+ filter.setPartitaIva(vatNumber);
+
+ AppointmentNdgRequest.Pagination pagination = new AppointmentNdgRequest.Pagination();
+ pagination.setTargetPage(AppointmentApiConstant.TARGET_PAGE_SIZE);
+ pagination.setRecordsPerPage(AppointmentApiConstant.RECORD_PER_PAGE_SIZE);
+
+ request.setFilter(filter);
+ request.setPagination(pagination);
+ return request;
+ }
+
+ private static String getAppointmentVisuraRequest(CompanyEntity company, String areaCode) {
+
+ AppointmentVisuraRequest visuraRequest = new AppointmentVisuraRequest();
+ AppointmentVisuraRequest.VisuraInput input = new AppointmentVisuraRequest.VisuraInput();
+ input.setPartitaIva(company.getVatNumber());
+ input.setCodiceFiscale(company.getCodiceFiscale());
+ input.setCodArea(areaCode);
+ input.setVisuraMode(AppointmentApiConstant.VISURA_MODE);
+ input.setVisuraProvider(AppointmentApiConstant.VISURA_PROVIDER);
+ input.setCodAgente(AppointmentApiConstant.COD_AGENTE);
+ input.setAnagraficaLegame(AppointmentApiConstant.IS_ANAGRAFICA_LEGAME);
+ input.setCreaAnagrafica(AppointmentApiConstant.CREA_ANAGRAFICA);
+ input.setFromRating(AppointmentApiConstant.IS_FROM_RATING);
+ input.setSalvaDocumenti(AppointmentApiConstant.SALVA_DOCUMENTI);
+ input.setVisuraType(AppointmentApiConstant.VISURA_TYPE);
+ visuraRequest.setInput(input);
+ return Utils.convertObjectToJson(visuraRequest);
+ }
+
+ private String parseNdgFromVisuraListResponse(String jsonResponse) {
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode rootNode = objectMapper.readTree(jsonResponse);
+ JsonNode dataNode = rootNode.get(GepafinConstant.DATA_STRING);
+
+ if (dataNode != null && dataNode.isArray() && dataNode.size() > 0) {
+ JsonNode firstEntry = dataNode.get(0);
+ JsonNode ndgClienteNode = firstEntry.get("ndgCliente");
+ if (ndgClienteNode != null && ndgClienteNode.get("code") != null) {
+ String code = ndgClienteNode.get("code").asText();
+ return normalizeNullValue(code);
+ }
+ }
+ log.warn("NDG not found in Visura List API response.");
+ return null;
+ } catch (Exception e) {
+ log.error("Failed to parse NDG from Visura List API response: {}", e.getMessage(), e);
+ throw new RuntimeException("Error parsing NDG from Visura List API response", e);
+ }
+ }
+
+ public AppointmentLoginResponse parseLoginResponse(String jsonResponse) {
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode rootNode = objectMapper.readTree(jsonResponse);
+ JsonNode dataNode = rootNode.get(GepafinConstant.DATA_STRING);
+
+ if (dataNode != null) {
+ AppointmentLoginResponse response = new AppointmentLoginResponse();
+ response.setTokenId(dataNode.get("tokenId").asText());
+ JsonNode areasNode = dataNode.get("areas");
+ if (areasNode != null && areasNode.isArray() && areasNode.size() > 0) {
+ response.setAreaCode(areasNode.get(0).get("code").asText());
+ }
+ response.setCompanyId(dataNode.get("companyId").asLong());
+ return response;
+ } else {
+ throw new RuntimeException("Invalid JSON structure: Missing 'data' node.");
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to parse response from loginApi for odessa: " + e.getMessage(), e);
+ }
+ }
+
+ public AppointmentLoginResponse parseVisuraResponse(String jsonResponse) {
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode rootNode = objectMapper.readTree(jsonResponse);
+ JsonNode dataNode = rootNode.get(GepafinConstant.DATA_STRING);
+
+ if (dataNode != null) {
+ AppointmentLoginResponse response = new AppointmentLoginResponse();
+ response.setIdVisura(normalizeNullValue(dataNode.get(GepafinConstant.ID_VISURA_STRING).asText()));
+ response.setNdg(normalizeNullValue(dataNode.get(GepafinConstant.NDG_STRING).asText()));
+ return response;
+ } else {
+ throw new RuntimeException("Invalid JSON structure: Missing 'data' node.");
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to parse response: " + e.getMessage(), e);
+ }
+ }
+
+ public AppointmentLoginResponse parseNdgResponse(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;
+ }
+ JsonNode firstDataEntry = dataArray.get(0);
+ AppointmentLoginResponse response = new AppointmentLoginResponse();
+ if (firstDataEntry.has(GepafinConstant.NDG_STRING)) {
+ response.setNdg(normalizeNullValue(firstDataEntry.get(GepafinConstant.NDG_STRING).asText()));
+ }
+ return response;
+ } catch (Exception e) {
+ log.error("Failed to parse response: {}", e.getMessage(), e);
+ throw new RuntimeException("Failed to parse NDG response.", e);
+ }
+ }
+
+ private String normalizeNullValue(String value) {
+
+ return (value == null || GepafinConstant.NULL_STRING.equalsIgnoreCase(value.trim())) ? null : value;
+ }
+
+ public AppointmentCreationResponse createAppointment(Long applicationId, CreateAppointmentRequest createAppointmentRequest) {
+ // Validate the application
+ ApplicationEntity application = applicationService.validateApplication(applicationId);
+
+ AppointmentCreationResponse appointmentCreationResponse = new AppointmentCreationResponse();
+
+ ApplicationEntity oldApplicationData = Utils.getClonedEntityForData(application);
+ HubEntity hub = hubRepository.findByHubId(application.getHubId());
+
+ // Check hub UUID and enforce constraints
+ if (!hub.getUniqueUuid().equals(defaultHubUuid)) {
+ log.info("Appointment cannot be created for another Hub; default is required for Gepafin.");
+ throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NO_APPOINTMENT_FOR_ANOTHER_HUB));
+ }
+
+ try {
+ // Pre-check conditions for appointment creation
+ if (application.getNdg() != null && !Objects.equals(application.getNdgStatus(), GepafinConstant.NDG_IN_PROGRESS) && application.getAppointmentId() != null) {
+ appointmentCreationResponse.setAppointmentId(application.getAppointmentId());
+ throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPOINTMENT_ALREADY_CREATED));
+ // return appointmentCreationResponse;
+ }
+
+ if (application.getNdg() == null && Objects.equals(application.getNdgStatus(), GepafinConstant.NDG_IN_PROGRESS)) {
+ throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.NDG_NOT_FOUND_FOR_APPLICATION));
+ }
+
+ // Generate authorization token and fetch template data
+ String authorizationToken = getBearerToken(hub);
+ ResponseEntity response = appointmentApiService.getAppointmentTemplateForTemplateCreation(authorizationToken);
+
+ if (response.getStatusCode() != HttpStatus.OK) {
+ log.error("Failed to retrieve appointment template for appointment creation. Status: {}", response.getStatusCode());
+ throw new IllegalStateException("Failed to retrieve appointment template for appointment creation");
+ }
+
+ // Parse template data
+ String responseDataForTemplate = Utils.convertObjectToJson(response.getBody());
+ AppointmentCreationRequest templateRichiestaData = parseTemplateResponseData(responseDataForTemplate);
+
+ // Build the appointment request body
+ AppointmentCreationRequest appointmentCreationRequest = buildAppointmentCreationRequest(applicationId, createAppointmentRequest, hub.getAreaCode(),
+ templateRichiestaData);
+ String appointmentRequestBody = Utils.convertObjectToJson(appointmentCreationRequest);
+
+ // Make API call to create the appointment
+ ResponseEntity appointmentResponse = appointmentApiService.createAppointment(authorizationToken, context, appointmentRequestBody);
+ String appointmentId = extractAppointmentIdFromResponse(appointmentResponse);
+
+ if (appointmentId != null) {
+ // Update application with the appointment ID
+ application.setAppointmentId(appointmentId);
+ application.setStatus(ApplicationStatusTypeEnum.APPOINTMENT.getValue());
+ applicationRepository.save(application);
+
+ // Log version history
+ loggingUtil.addVersionHistory(
+ VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationData).newData(application).build());
+ }
+
+ appointmentCreationResponse.setAppointmentId(appointmentId);
+ return appointmentCreationResponse;
+
+ } catch (FeignException.Forbidden forbiddenException) {
+ log.error("403 Forbidden received while retrieving template. Regenerating token...");
+ regenerateTokenAndSave(hub);
+ return createAppointment(applicationId, createAppointmentRequest);
+ }
+ }
+
+ private String extractAppointmentIdFromResponse(ResponseEntity appointmentResponse) {
+
+ if (appointmentResponse.getBody() != null) {
+ Map responseBody = (Map) appointmentResponse.getBody();
+ if (responseBody.containsKey(GepafinConstant.DATA_STRING)) {
+ Map data = (Map) responseBody.get(GepafinConstant.DATA_STRING);
+ if (data != null && data.containsKey(GepafinConstant.ID_STRING)) {
+ return data.get(GepafinConstant.ID_STRING).toString();
+ }
+ }
+ }
+ return null;
+ }
+
+ public AppointmentCreationRequest parseTemplateResponseData(String jsonResponse) {
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode rootNode = objectMapper.readTree(jsonResponse);
+ JsonNode richiestaClienteArray = rootNode.path(GepafinConstant.DATA_STRING).path(GepafinConstant.RICHIESTA_CLIENTE_STRING);
+
+ AppointmentCreationRequest appointmentCreationRequest = new AppointmentCreationRequest();
+ AppointmentCreationRequest.Input input = new AppointmentCreationRequest.Input();
+
+ // Map `richiestaCliente` array
+ List richiestaClienteList = new ArrayList<>();
+ if (richiestaClienteArray.isArray()) {
+ for (JsonNode richiestaNode : richiestaClienteArray) {
+ richiestaClienteList.add(objectMapper.treeToValue(richiestaNode, AppointmentCreationRequest.RichiestaCliente.class));
+ }
+ }
+
+ input.setRichiestaCliente(richiestaClienteList);
+ appointmentCreationRequest.setInput(input);
+ return appointmentCreationRequest;
+
+ } catch (Exception e) {
+ log.error("Error parsing template response: {}", e.getMessage(), e);
+ throw new IllegalStateException("Failed to parse template response", e);
+ }
+ }
+
+ public AppointmentCreationRequest buildAppointmentCreationRequest(Long applicationId, CreateAppointmentRequest createAppointmentRequest, String areaCode,
+ AppointmentCreationRequest templateRichiestaData) {
+
+ ApplicationEntity application = applicationService.validateApplication(applicationId);
+ CreateAppointmentRequest.Nota nota = createAppointmentRequest.getNota();
+
+ AppointmentCreationRequest appointmentCreationRequest = new AppointmentCreationRequest();
+ AppointmentCreationRequest.Input input = new AppointmentCreationRequest.Input();
+
+ // Set Input Fields
+ input.setId(areaCode);
+ input.setNdg(application.getNdg());
+
+ // Populate richiestaCliente from template data
+ List richiestaClienteList = new ArrayList<>();
+ for (AppointmentCreationRequest.RichiestaCliente templateRichiesta : templateRichiestaData.getInput().getRichiestaCliente()) {
+ AppointmentCreationRequest.RichiestaCliente richiestaCliente = new AppointmentCreationRequest.RichiestaCliente();
+ BeanUtils.copyProperties(templateRichiesta, richiestaCliente);
+
+ // Add specific `nota`
+ AppointmentCreationRequest.Nota requestNota = new AppointmentCreationRequest.Nota();
+ requestNota.setTitolo(nota.getTitolo());
+ requestNota.setTesto(nota.getTesto());
+ richiestaCliente.setNota(requestNota);
+
+ richiestaClienteList.add(richiestaCliente);
+ }
+
+ input.setRichiestaCliente(richiestaClienteList);
+ appointmentCreationRequest.setInput(input);
+ return appointmentCreationRequest;
+ }
+
+ public DocumentUploadResponse uploadDocumentToExternalSystem(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
+ // Check if the document is already being processed
+ DocumentEntity systemDoc = documentDao.validateDocument(documentId);
+
+ Claims claims = tokenProvider.getClaimsFromToken(tokenProvider.extractTokenFromRequest(request));
+ Long hubId = Utils.extractHubIdFromPayload(claims.getSubject());
+ if (systemDoc.getDocumentAttachmentId() != null) {
+ // If the documentAttachmentId is already set, return the response
+ log.info("Document already uploaded with documentAttachmentId: {}", systemDoc.getDocumentAttachmentId());
+ DocumentUploadResponse response = new DocumentUploadResponse();
+ 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);
+
+ 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 null;
+ // 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);
+
+ if (!hub.getUniqueUuid().equals(defaultHubUuid)) {
+ 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));
+ }
+
+ log.info("Got Document in system: {}", systemDoc);
+ String oldUrl = systemDoc.getFilePath();
+ String authorizationToken = getBearerToken(hub);
+
+ try {
+ File localFile = downloadFileFromS3(oldUrl);
+ MultipartFile multipartFile = convertFileToMultipartFile(localFile);
+
+ UploadDocToExternalSystemRequest externalSystemRequest = new UploadDocToExternalSystemRequest();
+ externalSystemRequest.setInput(getUploadDocumentInput(docToExternalSystemRequest));
+
+ String uploadDocRequest = Utils.convertObjectToJson(externalSystemRequest);
+ ResponseEntity uploadedDocumentData = appointmentApiService.uploadDocumentToExternalSystemForAppointment(authorizationToken, context, uploadDocRequest,
+ multipartFile);
+
+ 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));
+ }
+
+ // Save the documentAttachmentId to the database
+ systemDoc.setDocumentAttachmentId(parsedResponse.getDocumentAttachmentId());
+ documentRepository.save(systemDoc);
+
+ log.info("Document uploaded successfully to external system: {}", parsedResponse);
+ } catch (FeignException.Forbidden forbiddenException) {
+ log.error("403 Forbidden received while uploading document. Regenerating token...");
+ regenerateTokenAndSave(hub);
+ uploadDocumentToExternalSystemSync(documentId, docToExternalSystemRequest);
+ } catch (Exception e) {
+ log.error("Exception during document upload: {}", e.getMessage(), e);
+ throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.EXTERNAL_DOCUMENT_UPLOAD_FAILURE_MSG));
+ }
+ }
+
+ private UploadDocToExternalSystemRequest.Input getUploadDocumentInput(UploadDocToExternalSystemRequest docToExternalSystemRequest) {
+
+ UploadDocToExternalSystemRequest.Input input = new UploadDocToExternalSystemRequest.Input();
+ input.setIdTipoProtocollo(docToExternalSystemRequest.getInput().getIdTipoProtocollo());
+ input.setIdClassificazione(docToExternalSystemRequest.getInput().getIdClassificazione());
+ input.setFlagDaFirmare(flagDaFirmare);
+ input.setDescrizione(docToExternalSystemRequest.getInput().getDescrizione());
+
+ UploadDocToExternalSystemRequest.Input.Attributes attributes = new UploadDocToExternalSystemRequest.Input.Attributes();
+ attributes.setNdg(docToExternalSystemRequest.getInput().getAttributes().getNdg());
+ attributes.setEmail(docToExternalSystemRequest.getInput().getAttributes().getEmail());
+
+ input.setAttributes(attributes);
+ return input;
+ }
+
+ public static MultipartFile convertFileToMultipartFile(File file) throws IOException {
+
+ FileInputStream input = new FileInputStream(file);
+ return new MockMultipartFile(file.getName(), file.getName(), MediaType.APPLICATION_OCTET_STREAM_VALUE, input);
+ }
+
+ private File downloadFileFromS3(String fileUrl) throws Exception {
+
+ String key = extractS3KeyFromUrl(fileUrl);
+ File localFile = new File(GepafinConstant.TEMP_FILE_PATH + extractFileName(key));
+
+ GetObjectRequest getObjectRequest = new GetObjectRequest(OLD_BUCKET, key);
+
+ try (InputStream s3Stream = s3Client.getObject(getObjectRequest).getObjectContent(); FileOutputStream outputStream = new FileOutputStream(localFile)) {
+ s3Stream.transferTo(outputStream);
+ }
+
+ log.info("Downloaded file from old S3 bucket: {}", key);
+ return localFile;
+ }
+
+ private String extractS3KeyFromUrl(String url) {
+
+ return url.replace(s3Url, "");
+ }
+
+ private String extractFileName(String filePath) {
+
+ String[] parts = filePath.split("/");
+ return parts[parts.length - 1];
+
+ }
+
+ public DocumentUploadResponse parseDocumentUploadResponse(String jsonResponse) {
+
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ JsonNode rootNode = objectMapper.readTree(jsonResponse);
+
+ // Navigate to the "data" node
+ JsonNode dataNode = rootNode.get(GepafinConstant.DATA_STRING);
+ if (dataNode != null) {
+ DocumentUploadResponse response = new DocumentUploadResponse();
+
+ // Extract "documentAttachmentId"
+ JsonNode documentAttachmentIdNode = dataNode.get(GepafinConstant.DOCUMENT_ATTACHMENT_ID_STRING);
+ if (documentAttachmentIdNode != null) {
+ response.setDocumentAttachmentId(documentAttachmentIdNode.asText());
+ } else {
+ throw new RuntimeException("Invalid JSON structure: Missing 'documentAttachmentId' node.");
+ }
+
+ return response;
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to parse response: " + e.getMessage(), e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java
index b23e4785..e1dbe853 100644
--- a/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java
+++ b/src/main/java/net/gepafin/tendermanagement/dao/DocumentDao.java
@@ -6,6 +6,7 @@ import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.enums.*;
import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
+import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository;
import net.gepafin.tendermanagement.repositories.ApplicationRepository;
import net.gepafin.tendermanagement.util.LoggingUtil;
import net.gepafin.tendermanagement.util.Utils;
@@ -54,7 +55,7 @@ public class DocumentDao {
private S3PathConfig s3ConfigBean;
@Autowired
- private ApplicationRepository applicationFormRepository;
+ private ApplicationRepository applicationRepository;
@Autowired
ApplicationService applicationService;
@@ -65,6 +66,9 @@ public class DocumentDao {
@Autowired
ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository;
+ @Autowired
+ private ApplicationEvaluationRepository applicationEvaluationRepository;
+
@Value("${aws.s3.bucket.name}")
private String bucketName;
@@ -77,7 +81,7 @@ public class DocumentDao {
// @Value("${aws.s3.url.folder}")
// private String s3Folder;
- public List uploadFiles(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) {
+ public List uploadFiles(Long userId,List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) {
List documentEntities = new ArrayList<>();
Long source = resolveSourceId(sourceId, sourceType);
@@ -91,6 +95,7 @@ public class DocumentDao {
documentEntity.setType(fileType.getValue());
documentEntity.setFilePath(uploadFileOnAmazonS3Response.getFilePath());
documentEntity.setIsDeleted(false);
+ documentEntity.setUploadedBy(userId);
documentEntities.add(documentEntity);
}
}
@@ -116,6 +121,14 @@ public class DocumentDao {
userActionContext = UserActionContextEnum.UPLOAD_APPLICATION_DOCUMENT;
} else if (fileType.equals(DocumentTypeEnum.IMAGES) && sourceType.equals(DocumentSourceTypeEnum.APPLICATION)) {
userActionContext = UserActionContextEnum.UPLOAD_APPLICATION_IMAGES;
+ }else if (fileType.equals(DocumentTypeEnum.DOCUMENT) && sourceType.equals(DocumentSourceTypeEnum.AMENDMENT)) {
+ userActionContext = UserActionContextEnum.UPLOAD_AMENDMENT_DOCUMENT;
+ } else if (fileType.equals(DocumentTypeEnum.IMAGES) && sourceType.equals(DocumentSourceTypeEnum.AMENDMENT)) {
+ userActionContext = UserActionContextEnum.UPLOAD_AMENDMENT_IMAGES;
+ }else if (fileType.equals(DocumentTypeEnum.DOCUMENT) && sourceType.equals(DocumentSourceTypeEnum.EVALUATION)) {
+ userActionContext = UserActionContextEnum.UPLOAD_EVALUATION_DOCUMENT;
+ } else if (fileType.equals(DocumentTypeEnum.IMAGES) && sourceType.equals(DocumentSourceTypeEnum.EVALUATION)) {
+ userActionContext = UserActionContextEnum.UPLOAD_EVALUATION_IMAGES;
}
return userActionContext;
@@ -137,15 +150,21 @@ public class DocumentDao {
Long applicationId = 0L;
Long amendmentId = 0L;
+ Long evaluationId = 0L;
Long callId = sourceId;
if (type == DocumentSourceTypeEnum.APPLICATION) {
applicationId = sourceId;
- callId = applicationFormRepository.findCallIdById(applicationId);
+ callId = applicationRepository.findCallIdById(applicationId);
} else if (type == DocumentSourceTypeEnum.AMENDMENT) {
amendmentId = sourceId;
ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId);
applicationId = applicationEntity.getId();
callId = applicationEntity.getCall().getId();
+ }else if (type == DocumentSourceTypeEnum.EVALUATION) {
+ evaluationId = sourceId;
+ ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId);
+ applicationId = applicationEntity.getId();
+ callId = applicationEntity.getCall().getId();
}
try {
String s3Path = generateS3Path(type, callId, applicationId, amendmentId);
@@ -188,6 +207,7 @@ public class DocumentDao {
Long callId = null;
Long applicationId = null;
Long amendmentId = null;
+ Long evaluationId = null;
if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(documentEntity.getSource())) {
callId = documentEntity.getSourceId();
@@ -201,8 +221,12 @@ public class DocumentDao {
ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId);
applicationId = applicationEntity.getId();
callId = applicationEntity.getCall().getId();
+ } else if(DocumentSourceTypeEnum.EVALUATION.getValue().equalsIgnoreCase(documentEntity.getSource())){
+ evaluationId = documentEntity.getSourceId();
+ ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId);
+ applicationId = applicationEntity.getId();
+ callId = applicationEntity.getCall().getId();
}
-
deleteFileFromS3(documentEntity, callId, applicationId,amendmentId);
}
@@ -241,8 +265,9 @@ public class DocumentDao {
Long callId=null;
Long applicationId=null;
Long amendmentId=null;
+ Long evaluationId=null;
if (type.equals(DocumentSourceTypeEnum.APPLICATION)) {
- callId = applicationFormRepository.findCallIdById(id);
+ callId = applicationRepository.findCallIdById(id);
applicationId = id;
}
else if(type.equals(DocumentSourceTypeEnum.AMENDMENT)){
@@ -250,7 +275,13 @@ public class DocumentDao {
ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId);
applicationId = applicationEntity.getId();
callId = applicationEntity.getCall().getId();
+ }else if(type.equals(DocumentSourceTypeEnum.EVALUATION)){
+ evaluationId = id;
+ ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId);
+ applicationId = applicationEntity.getId();
+ callId = applicationEntity.getCall().getId();
}
+
else {
callId = id;
applicationId = 0L;
diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java
index a7606c9a..4601ef8c 100644
--- a/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java
+++ b/src/main/java/net/gepafin/tendermanagement/dao/ProtocolDao.java
@@ -4,6 +4,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime;
import jakarta.servlet.http.HttpServletRequest;
+import net.gepafin.tendermanagement.enums.ProtocolTypeEnum;
import net.gepafin.tendermanagement.enums.VersionActionTypeEnum;
import net.gepafin.tendermanagement.model.request.VersionHistoryRequest;
import net.gepafin.tendermanagement.util.LoggingUtil;
@@ -42,7 +43,7 @@ public class ProtocolDao {
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.setCall(applicationEntity.getCall().getId());
LocalDateTime utcDateTime = DateTimeUtil.DateServerToUTC(LocalDateTime.now());
@@ -51,6 +52,11 @@ public class ProtocolDao {
protocolEntity.setTime(LocalTime.now());
protocolEntity.setApplicationId(applicationEntity.getId());
protocolEntity.setHubId(hubId);
+ if(Boolean.TRUE.equals(isForApplication)){
+ protocolEntity.setType(ProtocolTypeEnum.INPUT.getValue());
+ }else {
+ protocolEntity.setType(ProtocolTypeEnum.OUTPUT.getValue());
+ }
protocolRepository.save(protocolEntity);
/** This code is responsible for adding a version history log for "create protocol" operation. **/
diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java
index 4b3fe79c..8a8701a1 100644
--- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java
+++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java
@@ -50,4 +50,7 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity {
@Column(name = "end_date")
private LocalDateTime endDate;
+ @Column(name = "amendment_document")
+ private String amendmentDocument;
+
}
diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java
index 6e65bf83..39e26f4b 100644
--- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java
+++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEntity.java
@@ -42,4 +42,17 @@ public class ApplicationEntity extends BaseEntity {
@ManyToOne
@JoinColumn(name = "USER_WITH_COMPANY_ID")
private UserWithCompanyEntity userWithCompany;
+
+ @Column(name = "NDG")
+ private String ndg;
+
+ @Column(name = "ID_VISURA")
+ private String idVisura;
+
+ @Column(name = "NDG_STATUS")
+ private String ndgStatus;
+
+ @Column(name = "APPOINTMENT_ID")
+ private String appointmentId;
+
}
\ No newline at end of file
diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java
index e33881b1..45a8c842 100644
--- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java
+++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java
@@ -22,6 +22,9 @@ public class ApplicationEvaluationEntity extends BaseEntity{
@Column(name = "checklist")
private String checklist;
+ @Column(name = "EVALUATION_DOCUMENT")
+ private String evaluationDocument;
+
@Column(name = "file")
private String file;
@@ -58,4 +61,5 @@ public class ApplicationEvaluationEntity extends BaseEntity{
@Column(name = "STOP_DATE_TIME")
private LocalDateTime stopDateTime;
+
}
diff --git a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java
index ed50268f..e3709ef7 100644
--- a/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java
+++ b/src/main/java/net/gepafin/tendermanagement/entities/CompanyEntity.java
@@ -62,5 +62,7 @@ public class CompanyEntity extends BaseEntity{
@ManyToOne
@JoinColumn(name = "HUB_ID")
private HubEntity hub;
-
+
+ @Column(name = "NDG")
+ private String ndg;
}
diff --git a/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java
index fc15a82d..08bfd623 100644
--- a/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java
+++ b/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java
@@ -29,4 +29,10 @@ public class DocumentEntity extends BaseEntity{
@Column(name ="IS_DELETED", nullable = false)
private Boolean isDeleted = false;
+ @Column(name="DOCUMENT_ATTACHMENT_ID")
+ private String documentAttachmentId;
+
+ @Column(name="uploaded_by")
+ private Long uploadedBy;
+
}
diff --git a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java
index 2e219acf..52aa6cc2 100644
--- a/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java
+++ b/src/main/java/net/gepafin/tendermanagement/entities/HubEntity.java
@@ -54,4 +54,13 @@ public class HubEntity extends BaseEntity{
@Column(name = "EMAIL_SERVICE_CONFIG")
private String emailServiceConfig;
+
+ @Column(name = "AUTH_TOKEN")
+ private String authToken;
+
+ @Column(name = "APPOINTMENT_AUTH_TOKEN_ID")
+ private String appointmentAuthTokenId;
+
+ @Column(name = "AREA_CODE")
+ private String areaCode;
}
diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ProtocolEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ProtocolEntity.java
index ad57c1ee..47dc5065 100644
--- a/src/main/java/net/gepafin/tendermanagement/entities/ProtocolEntity.java
+++ b/src/main/java/net/gepafin/tendermanagement/entities/ProtocolEntity.java
@@ -28,4 +28,7 @@ public class ProtocolEntity extends BaseEntity {
@Column(name="HUB_ID")
private Long hubId;
+ @Column(name = "type")
+ private String type;
+
}
diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java
index db6fe287..b6fd00b3 100644
--- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java
+++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationStatusTypeEnum.java
@@ -12,7 +12,10 @@ public enum ApplicationStatusTypeEnum {
SOCCORSO("SOCCORSO"),
APPROVED("APPROVED"),
REJECTED("REJECTED"),
- EVALUATION("EVALUATION");
+ EVALUATION("EVALUATION"),
+ APPOINTMENT("APPOINTMENT"),
+ NDG("NDG"),
+ ADMISSIBLE("ADMISSIBLE");
private String value;
diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java
index 556a9949..05b42e3b 100644
--- a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java
+++ b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java
@@ -6,6 +6,7 @@ public enum DocOtherSourceTypeEnum {
TEMPLATE("TEMPLATE"),
DELETED_USER_DELEGATION("DELETED_USER_DELEGATION"),
DELETED_APPLICATION("DELETED_APPLICATION"),
+ DELETED_EVALUATION("DELETED_EVALUATION"),
DELETED_CALL("DELETED_CALL"),
DELETED_AMENDMENT("DELETED_AMENDMENT");
diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java
index 7ac28ac7..e2b121e7 100644
--- a/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java
+++ b/src/main/java/net/gepafin/tendermanagement/enums/DocumentSourceTypeEnum.java
@@ -4,7 +4,7 @@ public enum DocumentSourceTypeEnum {
CALL("CALL"),
APPLICATION("APPLICATION"),
-
+ EVALUATION("EVALUATION"),
AMENDMENT("AMENDMENT");
private String value;
diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ProtocolTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ProtocolTypeEnum.java
new file mode 100644
index 00000000..f890fb42
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/enums/ProtocolTypeEnum.java
@@ -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);
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/enums/RoleStatusEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/RoleStatusEnum.java
index 3659856d..31d3e9b8 100644
--- a/src/main/java/net/gepafin/tendermanagement/enums/RoleStatusEnum.java
+++ b/src/main/java/net/gepafin/tendermanagement/enums/RoleStatusEnum.java
@@ -7,7 +7,8 @@ public enum RoleStatusEnum {
ROLE_BENEFICIARY("ROLE_BENEFICIARY"),
ROLE_SUPER_ADMIN("ROLE_SUPER_ADMIN"),
ROLE_PRE_INSTRUCTOR("ROLE_PRE_INSTRUCTOR"),
- ROLE_GEPAFIN_OPERATOR("ROLE_GEPAFIN_OPERATOR");
+ ROLE_GEPAFIN_OPERATOR("ROLE_GEPAFIN_OPERATOR"),
+ ROLE_INSTRUCTOR_MANAGER("ROLE_INSTRUCTOR_MANAGER");
private String value;
diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java
index 7023b40b..20f917fe 100644
--- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java
+++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java
@@ -118,6 +118,10 @@ public enum UserActionContextEnum {
UPDATE_DOCUMENT("UPDATE_DOCUEMENT"),
UPDATE_IMAGES("UPDATE_IMAGES"),
GET_DOCUMENT("GET_DOCUMENT"),
+ UPLOAD_AMENDMENT_DOCUMENT("UPLOAD_AMENDMENT_DOCUMENT"),
+ UPLOAD_AMENDMENT_IMAGES("UPLOAD_AMENDMENT_IMAGES"),
+ UPLOAD_EVALUATION_DOCUMENT("UPLOAD_EVALUATION_DOCUMENT"),
+ UPLOAD_EVALUATION_IMAGES("UPLOAD_EVALUATION_IMAGES"),
/** Assigned flow context **/
CREATE_UPDATE_FLOW("CREATE_UPDATE_FLOW"),
@@ -136,6 +140,7 @@ public enum UserActionContextEnum {
UPDATE_EVALUATION_CRITERIA("UPDATE_EVALUATION_CRITERIA"),
DELETE_EVALUATION_CRITERIA("DELETE_EVALUATION_CRITERIA"),
CREATE_EVALUATION_CRITERIA("CREATE_EVALUATION_CRITERIA"),
+ UPLOAD_EVALUATION_DOC("UPLOAD_EVALUATION_DOC"),
/** communication action context **/
ADD_COMMENT_TO_AMENDMENT_REQUEST("ADD_COMMENT_TO_AMENDMENT_REQUEST"),
@@ -151,7 +156,12 @@ public enum UserActionContextEnum {
/** scheduler action context **/
AMENDMENT_EXPIRATION_SCHEDULER("AMENDMENT_EXPIRATION_SCHEDULER"),
- EVALUATION_EXPIRATION_SCHEDULER("EVALUATION_EXPIRATION_SCHEDULER");
+ EVALUATION_EXPIRATION_SCHEDULER("EVALUATION_EXPIRATION_SCHEDULER"),
+
+ /** appointment action context **/
+ CHECK_OR_CREATE_NDG_CODE("CHECK_OR_CREATE_NDG_CODE"),
+ CREATE_APPOINTMENT("CREATE_APPOINTMENT"),
+ UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM("UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM");
private final String value;
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentDetailsRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentDetailsRequest.java
new file mode 100644
index 00000000..b0dc2adb
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentDetailsRequest.java
@@ -0,0 +1,15 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AmendmentDetailsRequest {
+
+ private String fieldId;
+
+ private Long amendmentId;
+
+ private Boolean valid;
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFieldRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFieldRequest.java
new file mode 100644
index 00000000..b7efa539
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFieldRequest.java
@@ -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 valid = false;
+
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFormField.java b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFormField.java
index 95f158c3..35b3521a 100644
--- a/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFormField.java
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFormField.java
@@ -9,9 +9,13 @@ public class AmendmentFormField {
private String fieldId;
+ private String label;
+
private String fieldValue;
- private String isUploadedBy;
+ private Boolean valid;
+
+
public enum AmendmentIsUploadedByEnum {
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFormFieldRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFormFieldRequest.java
new file mode 100644
index 00000000..3376d76c
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AmendmentFormFieldRequest.java
@@ -0,0 +1,17 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class AmendmentFormFieldRequest {
+
+ private String fieldId;
+
+ private Object fieldValue;
+
+ private Boolean valid;
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentRequestBean.java
index 94141ef0..7ab254d8 100644
--- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentRequestBean.java
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentRequestBean.java
@@ -7,5 +7,7 @@ import lombok.Data;
@Data
public class ApplicationAmendmentRequestBean {
private String note;
- private List applicationFormFields;
+ private List applicationFormFields;
+ private String amendmentDocuments;
+ private String amendmentNotes;
}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java
index df29c1d8..6616c288 100644
--- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationEvaluationRequest.java
@@ -10,6 +10,8 @@ public class ApplicationEvaluationRequest {
private List criteria;
private List checklist;
private List files;
+ private List evaluationDocument;
+ private List amendmentDetails;
private String note;
private ApplicationStatusForEvaluation applicationStatus;
private String motivation;
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java
new file mode 100644
index 00000000..a877a620
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentCreationRequest.java
@@ -0,0 +1,42 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AppointmentCreationRequest {
+
+ private Input input;
+
+ @Data
+ public static class Input {
+ private String id;
+ private String ndg;
+ private List richiestaCliente;
+ }
+
+ @Data
+ public static class RichiestaCliente {
+ private String codAbi;
+ private String codCab;
+ private Integer durataMesiFinanziamento;
+ private Integer idMotivazione;
+ private String idNota;
+ private String importoAgevolato;
+ private Double importoBreveTermine;
+ private String importoMedioLungoTermine;
+ private String codTipoProdotto;
+ private String codCategoriaProdotto;
+ private String codFormaTecnica;
+ private String codProdotto;
+ private String codOperazione;
+ private Nota nota;
+ }
+
+ @Data
+ public static class Nota {
+ private String titolo;
+ private String testo;
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentNdgRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentNdgRequest.java
new file mode 100644
index 00000000..639c8b5d
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentNdgRequest.java
@@ -0,0 +1,20 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.Data;
+
+@Data
+public class AppointmentNdgRequest {
+ private Filter filter;
+ private Pagination pagination;
+
+ @Data
+ public static class Filter {
+ private String partitaIva;
+ }
+
+ @Data
+ public static class Pagination {
+ private int targetPage;
+ private int recordsPerPage;
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentVisuraListRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentVisuraListRequest.java
new file mode 100644
index 00000000..da5b8720
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentVisuraListRequest.java
@@ -0,0 +1,14 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.Data;
+
+@Data
+public class AppointmentVisuraListRequest {
+
+ private AppointmentVisuraListRequest.VisuraFilter filter;
+
+ @Data
+ public static class VisuraFilter {
+ private String idVisura;
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentVisuraRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentVisuraRequest.java
new file mode 100644
index 00000000..59546ee6
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/AppointmentVisuraRequest.java
@@ -0,0 +1,28 @@
+package net.gepafin.tendermanagement.model.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.Setter;
+
+@Data
+public class AppointmentVisuraRequest {
+ private VisuraInput input;
+
+ @Data
+ public static class VisuraInput {
+ private String codiceFiscale;
+ private String partitaIva;
+ private boolean creaAnagrafica;
+ private boolean salvaDocumenti;
+ private String visuraProvider;
+ private String visuraType;
+ private String visuraMode;
+ private String codArea;
+ private String codAgente;
+ @JsonProperty("isFromRating")
+ private boolean isFromRating;
+ @JsonProperty("isAnagraficaLegame")
+ private boolean isAnagraficaLegame;
+ }
+}
+
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/CreateAppointmentRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/CreateAppointmentRequest.java
new file mode 100644
index 00000000..667ba581
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/CreateAppointmentRequest.java
@@ -0,0 +1,17 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.Data;
+
+@Data
+public class CreateAppointmentRequest {
+ private Double importoBreveTermine;
+ private Integer durataMesiFinanziamento;
+ private Nota nota;
+
+ @Data
+ public static class Nota {
+ private String titolo;
+
+ private String testo;
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/EvaluationDocumentRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/EvaluationDocumentRequest.java
new file mode 100644
index 00000000..79aed45c
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/EvaluationDocumentRequest.java
@@ -0,0 +1,15 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.Data;
+
+@Data
+public class EvaluationDocumentRequest {
+
+ private String fieldId;
+
+ private String nameValue;
+
+ private String fileValue;
+
+ private Boolean valid;
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/UploadDocToExternalSystemRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/UploadDocToExternalSystemRequest.java
new file mode 100644
index 00000000..bd3a3097
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/request/UploadDocToExternalSystemRequest.java
@@ -0,0 +1,23 @@
+package net.gepafin.tendermanagement.model.request;
+
+import lombok.Data;
+
+@Data
+public class UploadDocToExternalSystemRequest {
+ private Input input;
+
+ @Data
+ public static class Input {
+ private Long idTipoProtocollo;
+ private Long idClassificazione;
+ private Boolean flagDaFirmare;
+ private String descrizione;
+ private Attributes attributes;
+
+ @Data
+ public static class Attributes {
+ private String ndg;
+ private String email;
+ }
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AmendmentDetailsResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/AmendmentDetailsResponseBean.java
new file mode 100644
index 00000000..eb9ee866
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/AmendmentDetailsResponseBean.java
@@ -0,0 +1,12 @@
+package net.gepafin.tendermanagement.model.response;
+
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class AmendmentDetailsResponseBean {
+ private String amendmentDocuments;
+ private String amendmentNotes;
+ private Boolean valid;
+
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AmendmentDocumentResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/AmendmentDocumentResponseBean.java
new file mode 100644
index 00000000..21fc1a09
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/AmendmentDocumentResponseBean.java
@@ -0,0 +1,15 @@
+package net.gepafin.tendermanagement.model.response;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AmendmentDocumentResponseBean {
+
+ private Long amendmentId;
+ private String fieldId;
+ private String label;
+ private Boolean valid;
+ private List fileDetail ;
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java
index 5523098e..01390777 100644
--- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java
@@ -21,6 +21,9 @@ public class ApplicationAmendmentRequestResponse {
private String beneficiaryName;
private List formFields;
private List applicationFormFields;
+ private List amendmentDocuments;
+ private String amendmentNotes;
+ private Boolean valid;
private Long applicationId;
private Long applicationEvaluationId;
private LocalDateTime evaluationEndDate;
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java
index 3e5c3834..b890b327 100644
--- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java
@@ -21,6 +21,8 @@ public class ApplicationEvaluationResponse {
private List criteria;
private List checklist;
private List files;
+ private List evaluationDocument;
+ private List amendmentDetails;
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
private String beneficiary;
@@ -32,4 +34,6 @@ public class ApplicationEvaluationResponse {
private LocalDateTime callEndDate;
private String companyName;
private LocalDateTime assignedAt;
+ private String ndg;
+ private String appointmentId;
}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AppointmentCreationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AppointmentCreationResponse.java
new file mode 100644
index 00000000..80dd3ba0
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/AppointmentCreationResponse.java
@@ -0,0 +1,8 @@
+package net.gepafin.tendermanagement.model.response;
+
+import lombok.Data;
+
+@Data
+public class AppointmentCreationResponse {
+ private String appointmentId;
+}
\ No newline at end of file
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AppointmentLoginResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AppointmentLoginResponse.java
new file mode 100644
index 00000000..1d3b9c56
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/AppointmentLoginResponse.java
@@ -0,0 +1,16 @@
+package net.gepafin.tendermanagement.model.response;
+
+import lombok.Data;
+
+@Data
+public class AppointmentLoginResponse {
+
+ private String tokenId;
+ private String areaCode;
+ private Long companyId;
+ private String codecFiscale;
+ private String vatNumber;
+ private String ndg;
+ private String message;
+ private String idVisura;
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/DocumentResponseBean.java b/src/main/java/net/gepafin/tendermanagement/model/response/DocumentResponseBean.java
index f5706b10..307c4982 100644
--- a/src/main/java/net/gepafin/tendermanagement/model/response/DocumentResponseBean.java
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/DocumentResponseBean.java
@@ -25,4 +25,6 @@ public class DocumentResponseBean {
private LocalDateTime createdDate;
private LocalDateTime updatedDate;
+
+ private String documentAttachmentId;
}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/DocumentUploadResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/DocumentUploadResponse.java
new file mode 100644
index 00000000..956ef1cb
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/DocumentUploadResponse.java
@@ -0,0 +1,8 @@
+package net.gepafin.tendermanagement.model.response;
+
+import lombok.Data;
+
+@Data
+public class DocumentUploadResponse {
+ private String documentAttachmentId;
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/EvaluationDocumentResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/EvaluationDocumentResponse.java
new file mode 100644
index 00000000..94a4d881
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/EvaluationDocumentResponse.java
@@ -0,0 +1,14 @@
+package net.gepafin.tendermanagement.model.response;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class EvaluationDocumentResponse {
+ private String fieldId;
+ private String nameValue;
+ private Boolean valid;
+ private List fileValue ;
+
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/NdgResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/NdgResponse.java
new file mode 100644
index 00000000..991828c5
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/model/response/NdgResponse.java
@@ -0,0 +1,8 @@
+package net.gepafin.tendermanagement.model.response;
+
+import lombok.Data;
+
+@Data
+public class NdgResponse {
+ private String ndg;
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java
index 4a2e3252..ecb6b83d 100644
--- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java
+++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java
@@ -44,7 +44,7 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findFirstByIsDeletedFalseOrderByCreatedDateDesc();
boolean existsByApplicationIdAndIsDeletedFalse(Long applicationId);
+ @Query("SELECT app " +
+ "FROM ApplicationEntity app " +
+ "WHERE app.id = (SELECT aar.applicationId " +
+ "FROM ApplicationEvaluationEntity aar " +
+ "WHERE aar.id = :evaluationId AND aar.isDeleted = false)")
+ ApplicationEntity findApplicationByEvaluationId(Long evaluationId);
@Query("SELECT a FROM ApplicationEvaluationEntity a WHERE a.isDeleted = false AND a.endDate < :currentDate")
List findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate);
diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java
index 8877fbc7..db645f95 100644
--- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java
+++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java
@@ -42,6 +42,6 @@ public interface ApplicationRepository extends JpaRepository {
- Optional findByUniqueUuid(String hubUuid);
-
+ Optional findByUniqueUuid(String hubUuid);
+
+ @Query("SELECT h FROM HubEntity h WHERE h.id = :hubId")
+ HubEntity findByHubId(@Param("hubId") Long hubId);
}
diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java
index c7bde2db..454030af 100644
--- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java
+++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationEvaluationService.java
@@ -2,10 +2,12 @@ package net.gepafin.tendermanagement.service;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
-import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
+import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
+import java.util.List;
+
public interface ApplicationEvaluationService {
ApplicationEvaluationResponse createOrUpdateApplicationEvaluation(
HttpServletRequest request,
@@ -18,4 +20,5 @@ public interface ApplicationEvaluationService {
ApplicationEvaluationEntity validateApplicationEvaluation(Long applicationEvaluationId);
ApplicationEvaluationEntity validateApplicationEvaluationByApplicationId(Long applicationId);
+
}
diff --git a/src/main/java/net/gepafin/tendermanagement/service/AppointmentService.java b/src/main/java/net/gepafin/tendermanagement/service/AppointmentService.java
new file mode 100644
index 00000000..842901a4
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/service/AppointmentService.java
@@ -0,0 +1,16 @@
+package net.gepafin.tendermanagement.service;
+
+import jakarta.servlet.http.HttpServletRequest;
+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;
+
+public interface AppointmentService {
+ NdgResponse checkNdgForAppointment(HttpServletRequest request, Long applicationId);
+
+ AppointmentCreationResponse createAppointmentForApplication(HttpServletRequest request, Long applicationId, CreateAppointmentRequest createAppointmentRequest);
+
+ DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest);
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/service/DocumentService.java b/src/main/java/net/gepafin/tendermanagement/service/DocumentService.java
index 6012a273..c777f004 100644
--- a/src/main/java/net/gepafin/tendermanagement/service/DocumentService.java
+++ b/src/main/java/net/gepafin/tendermanagement/service/DocumentService.java
@@ -11,7 +11,7 @@ import java.util.List;
public interface DocumentService {
- public List uploadFile(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType);
+ public List uploadFile(HttpServletRequest request,List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType);
public void deleteFile(Long documentId);
diff --git a/src/main/java/net/gepafin/tendermanagement/service/feignClient/AppointmentApiService.java b/src/main/java/net/gepafin/tendermanagement/service/feignClient/AppointmentApiService.java
new file mode 100644
index 00000000..b193713b
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/service/feignClient/AppointmentApiService.java
@@ -0,0 +1,44 @@
+package net.gepafin.tendermanagement.service.feignClient;
+
+import net.gepafin.tendermanagement.constants.AppointmentApiConstant;
+import net.gepafin.tendermanagement.model.request.AppointmentNdgRequest;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+
+@FeignClient(value = "appointment-api-service", url = "${appointment.base.url}")
+public interface AppointmentApiService {
+
+ @PostMapping(value = AppointmentApiConstant.ODESSA_LOGIN, consumes = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity loginWithOdessa(@RequestHeader("auth") String authToken, @RequestHeader("source") String source, @RequestHeader("context") String context,
+ @RequestHeader("user") String user, @RequestHeader("password") String password, @RequestBody(required = false) Map body);
+
+ @PostMapping(value = AppointmentApiConstant.GET_NDG_BY_VAT_NUMBER, consumes = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity getNdgByVatNumber(@RequestBody AppointmentNdgRequest ndgRequest, @RequestHeader("Authorization") String token);
+
+ @PostMapping(value = AppointmentApiConstant.CREATE_VISURA, consumes = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity createVisura(@RequestBody String visuraRequest, @RequestHeader("Authorization") String token);
+
+ @GetMapping(value = AppointmentApiConstant.GET_VISURA_LIST, consumes = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity getVisuraList(@RequestBody String visuraRequest, @RequestHeader("Authorization") String token);
+
+ @GetMapping(value = AppointmentApiConstant.GET_APPOINTMENT_TEMPLATE, consumes = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity getAppointmentTemplateForTemplateCreation(@RequestHeader("Authorization") String token);
+
+ @PostMapping(value = AppointmentApiConstant.CREATE_APPOINTMENT_FROM_TEMPLATE, consumes = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity createAppointment(@RequestHeader("Authorization") String token, @RequestHeader("context") String context, String appointmentCreationRequest);
+
+ @PostMapping(value = AppointmentApiConstant.UPLOAD_APOOINTMENT_DOCUMENT, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ ResponseEntity uploadDocumentToExternalSystemForAppointment(@RequestHeader("Authorization") String token, @RequestHeader("context") String context,
+ @RequestPart("input") String uploadDocumentRequest, @RequestPart("file") MultipartFile file);
+}
+
+
diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java
index 0a6feb1f..3dd9035f 100644
--- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java
+++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationEvaluationServiceImpl.java
@@ -1,29 +1,24 @@
package net.gepafin.tendermanagement.service.impl;
import jakarta.servlet.http.HttpServletRequest;
-import net.gepafin.tendermanagement.config.Translator;
-import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.dao.ApplicationEvaluationDao;
import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity;
import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
-import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
+import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository;
import net.gepafin.tendermanagement.service.ApplicationEvaluationService;
import net.gepafin.tendermanagement.service.AssignedApplicationsService;
import net.gepafin.tendermanagement.util.Validator;
-import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
-import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundException;
-import net.gepafin.tendermanagement.web.rest.api.errors.Status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.Optional;
+import java.util.List;
@Service
public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationService {
@@ -36,6 +31,9 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe
private AssignedApplicationsService assignedApplicationsService;
@Autowired
private AssignedApplicationsRepository assignedApplicationsRepository;
+ @Autowired
+ private ApplicationEvaluationService applicationEvaluationService;
+
@Override
@Transactional(rollbackFor = Exception.class)
public ApplicationEvaluationResponse createOrUpdateApplicationEvaluation(
@@ -54,31 +52,12 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe
@Transactional(readOnly = true)
public ApplicationEvaluationResponse getApplicationEvaluationByApplicationId(
HttpServletRequest request, Long applicationId, Long assignedApplicationId) {
-
- if (applicationId == null && assignedApplicationId == null) {
- throw new CustomValidationException(
- Status.BAD_REQUEST,
- Translator.toLocale(GepafinConstant.EITHER_APPLICATION_OR_ASSIGNED_APPLICATION_ID_REQUIRED_MSG)
- );
- }
UserEntity preInstructor = validator.validateUser(request);
- Optional assignedApplicationsOptional =
- assignedApplicationsRepository.findByApplicationIdOrIdAndIsDeletedFalse(applicationId,assignedApplicationId);
-
- if (assignedApplicationId != null) {
- assignedApplicationsOptional = assignedApplicationsOptional.filter(a -> a.getId().equals(assignedApplicationId));
- }
- AssignedApplicationsEntity assignedApplications = assignedApplicationsOptional
- .orElseThrow(() -> new CustomValidationException(
- Status.BAD_REQUEST,
- Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_WITH_ID_MSG)
- ));
- validator.validatePreInstructor(request, assignedApplications.getUserId());
-
return applicationEvaluationDao.getApplicationEvaluationByApplicationId(
+ request,
preInstructor,
- assignedApplications.getApplication().getId(),
- assignedApplications.getId()
+ applicationId,
+ assignedApplicationId
);
}
@@ -98,4 +77,5 @@ public class ApplicationEvaluationServiceImpl implements ApplicationEvaluationSe
public ApplicationEvaluationEntity validateApplicationEvaluationByApplicationId(Long applicationId) {
return applicationEvaluationDao.validateApplicationEvaluationByApplicationId(applicationId);
}
+
}
diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AppointmentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AppointmentServiceImpl.java
new file mode 100644
index 00000000..2e7960df
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AppointmentServiceImpl.java
@@ -0,0 +1,37 @@
+package net.gepafin.tendermanagement.service.impl;
+
+import jakarta.servlet.http.HttpServletRequest;
+import net.gepafin.tendermanagement.dao.AppointmentDao;
+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 org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AppointmentServiceImpl implements AppointmentService {
+
+ @Autowired
+ private AppointmentDao appointmentDao;
+
+ @Override
+ public NdgResponse checkNdgForAppointment(HttpServletRequest request, Long applicationId) {
+
+ return appointmentDao.checkNdgForAppointment(applicationId);
+ }
+
+ @Override
+ public AppointmentCreationResponse createAppointmentForApplication(HttpServletRequest request, Long applicationId, CreateAppointmentRequest createAppointmentRequest) {
+
+ return appointmentDao.createAppointment(applicationId, createAppointmentRequest);
+ }
+
+ @Override
+ public DocumentUploadResponse uploadDocToExternalSystem(HttpServletRequest request, Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) {
+
+ return appointmentDao.uploadDocumentToExternalSystem(documentId, docToExternalSystemRequest);
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java
index 505d0da1..d7a46aa6 100644
--- a/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java
+++ b/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java
@@ -1,14 +1,17 @@
package net.gepafin.tendermanagement.service.impl;
import java.util.List;
+import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.dao.DocumentDao;
import net.gepafin.tendermanagement.entities.DocumentEntity;
+import net.gepafin.tendermanagement.entities.UserEntity;
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
import net.gepafin.tendermanagement.enums.DocumentTypeEnum;
import net.gepafin.tendermanagement.model.response.DocumentResponseBean;
import net.gepafin.tendermanagement.service.DocumentService;
+import net.gepafin.tendermanagement.util.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -22,9 +25,13 @@ public class DocumentServiceImpl implements DocumentService {
@Autowired
private DocumentDao documentDao;
+ @Autowired
+ private Validator validator;
@Override
- public List uploadFile(List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) {
- return documentDao.uploadFiles(files,sourceId,sourceType,fileType);
+ public List uploadFile(HttpServletRequest request,List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) {
+ Map userInfo = validator.getUserInfoFromToken(request);
+ Long userId = validator.getUserId(userInfo);
+ return documentDao.uploadFiles(userId,files,sourceId,sourceType,fileType);
}
@Override
public void deleteFile(Long documentId) {
diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java
index 23b8fd59..dac565e7 100644
--- a/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java
+++ b/src/main/java/net/gepafin/tendermanagement/service/impl/S3ReUploadMigrationService.java
@@ -12,10 +12,7 @@ import net.gepafin.tendermanagement.dao.S3PathConfig;
import net.gepafin.tendermanagement.entities.ApplicationEntity;
import net.gepafin.tendermanagement.entities.DocumentEntity;
import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum;
-import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository;
-import net.gepafin.tendermanagement.repositories.ApplicationRepository;
-import net.gepafin.tendermanagement.repositories.ApplicationSignedDocumentRepository;
-import net.gepafin.tendermanagement.repositories.DocumentRepository;
+import net.gepafin.tendermanagement.repositories.*;
import net.gepafin.tendermanagement.service.AmazonS3Service;
import net.gepafin.tendermanagement.service.ApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -73,6 +70,9 @@ public class S3ReUploadMigrationService {
@Autowired
private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository;
+ @Autowired
+ private ApplicationEvaluationRepository applicationEvaluationRepository;
+
@Autowired
private DocumentDao documentDao;
@@ -107,7 +107,7 @@ public class S3ReUploadMigrationService {
Long callId = null;
Long applicationId = null;
Long amendmentId = null;
-
+ Long evaluationId = null;
if (DocumentSourceTypeEnum.CALL.getValue().equalsIgnoreCase(document.getSource())) {
callId = document.getSourceId();
} else if (DocumentSourceTypeEnum.APPLICATION.getValue().equalsIgnoreCase(document.getSource())) {
@@ -120,8 +120,14 @@ public class S3ReUploadMigrationService {
ApplicationEntity applicationEntity = applicationAmendmentRequestRepository.findApplicationByAmendmentId(amendmentId);
applicationId = applicationEntity.getId();
callId = applicationEntity.getCall().getId();
+ } else if(DocumentSourceTypeEnum.EVALUATION.getValue().equalsIgnoreCase(document.getSource())){
+ evaluationId = document.getSourceId();
+ ApplicationEntity applicationEntity = applicationEvaluationRepository.findApplicationByEvaluationId(evaluationId);
+ applicationId = applicationEntity.getId();
+ callId = applicationEntity.getCall().getId();
}
+
documentDao.deleteFileFromS3(document,callId,applicationId,amendmentId);
processDocuments++;
diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java
index 319795ec..e2ab4521 100644
--- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java
+++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java
@@ -9,7 +9,6 @@ import net.gepafin.tendermanagement.constants.GepafinConstant;
import net.gepafin.tendermanagement.entities.UserActionEntity;
import net.gepafin.tendermanagement.entities.UserEntity;
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.VersionHistoryRequest;
import net.gepafin.tendermanagement.repositories.UserActionsRepository;
diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java
index 7524c306..7d5b6344 100644
--- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java
+++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java
@@ -19,12 +19,15 @@ import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.jsonwebtoken.Claims;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.servlet.http.HttpServletRequest;
+import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
+import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,6 +54,7 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.crypto.Cipher;
+import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
@@ -59,6 +63,9 @@ import static org.apache.commons.lang3.StringUtils.isEmpty;
public class Utils {
+// @Autowired
+// private static TokenProvider tokenProvider;
+
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)
@@ -580,4 +587,108 @@ public class Utils {
// Clear the RequestContextHolder after task execution
RequestContextHolder.resetRequestAttributes();
}
-}
+
+ public static String generateAuthTokenForLoginToOdessa() {
+
+ try {
+ // Your weak secret key
+ String secretKey = GepafinConstant.AUTH_JWT_SECRET_KEY;
+
+ // Header
+ String header = GepafinConstant.JWT_ALGO_HEADER;
+ String encodedHeader = Base64.getUrlEncoder().withoutPadding().encodeToString(header.getBytes(StandardCharsets.UTF_8));
+
+ // Payload
+ String payload = "{\"iat\":" + (System.currentTimeMillis() / 1000) + "}";
+ String encodedPayload = Base64.getUrlEncoder().withoutPadding().encodeToString(payload.getBytes(StandardCharsets.UTF_8));
+
+ // Combine header and payload
+ String dataToSign = encodedHeader + "." + encodedPayload;
+
+ // Sign the token manually
+ Mac mac = Mac.getInstance(GepafinConstant.HMAC_ALGO);
+ SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), GepafinConstant.HMAC_ALGO);
+ mac.init(secretKeySpec);
+ byte[] signatureBytes = mac.doFinal(dataToSign.getBytes(StandardCharsets.UTF_8));
+ String signature = Base64.getUrlEncoder().withoutPadding().encodeToString(signatureBytes);
+
+ // Return the final JWT
+ return dataToSign + "." + signature;
+ } catch (Exception 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 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;
+ }
+
+ // Method to convert a JSON string to an object of type T
+ public static T convertStringToObject(String jsonString, Class clazz) {
+ try {
+ return mapper.readValue(jsonString, clazz);
+ } catch (Exception e) {
+ e.printStackTrace();
+ // Handle the exception appropriately (e.g., throw a custom exception)
+ return null;
+ }
+ }
+
+ // Method to convert an object of type T to a JSON string
+ public static String convertObjectToString(T object) {
+ try {
+ return mapper.writeValueAsString(object);
+ } catch (Exception e) {
+ e.printStackTrace();
+ // Handle the exception appropriately (e.g., throw a custom exception)
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/gepafin/tendermanagement/util/Validator.java b/src/main/java/net/gepafin/tendermanagement/util/Validator.java
index e0814305..4e3335a6 100644
--- a/src/main/java/net/gepafin/tendermanagement/util/Validator.java
+++ b/src/main/java/net/gepafin/tendermanagement/util/Validator.java
@@ -90,6 +90,8 @@ public class Validator {
validateHubId(request, companyEntity.getHub().getId());
if (checkIsSuperAdmin()) {
return companyEntity;
+ } else if (checkIsInstructorManager()) {
+ return companyEntity;
}
Map userInfo = tokenProvider.getUserInfoAndUserIdFromToken(request);
companyService.validateUserWithCompny(getUserId(userInfo), companyId);
@@ -105,7 +107,7 @@ public class Validator {
}
}
- private Long getUserId(Map userInfo) {
+ public Long getUserId(Map userInfo) {
return Long.parseLong(userInfo.get("userId").toString());
}
@@ -127,8 +129,11 @@ public class Validator {
UserEntity requestedUser = userService.validateUser(userId);
validateHubId(request, requestedUser.getHub().getId());
- if (Boolean.FALSE.equals(user.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_SUPER_ADMIN.getValue()))
- && Boolean.FALSE.equals(user.getId().equals(userId))) {
+// if (Boolean.FALSE.equals(user.getRoleEntity().getRoleType().equals(RoleStatusEnum.ROLE_SUPER_ADMIN.getValue()))
+// && Boolean.FALSE.equals(user.getId().equals(userId)))
+ if (checkIsSuperAdmin() || checkIsInstructorManager()) {
+
+ } else if(Boolean.FALSE.equals(user.getId().equals(userId))) {
throw new ForbiddenAccessException(Status.FORBIDDEN,
Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
}
@@ -164,6 +169,11 @@ public class Validator {
validateHubId(request, preInstructorUser.getHub().getId());
}
return preInstructorUser;
+ } else if (checkIsInstructorManager()) {
+ if (preInstructorUserId != null) {
+ validateHubId(request, preInstructorUser.getHub().getId());
+ }
+ return preInstructorUser;
} else if (checkIsPreInstructor()) {
return validateUserId(request, preInstructorUserId);
} else {
@@ -171,5 +181,18 @@ public class Validator {
Translator.toLocale(GepafinConstant.PERMISSION_DENIED));
}
}
-
+
+ public Boolean checkIsInstructorManager() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+
+ if (authentication != null && authentication.isAuthenticated()) {
+ // Check if the user has the ROLE_INSTRUCTOR_MANAGER authority
+ for (GrantedAuthority authority : authentication.getAuthorities()) {
+ if (RoleStatusEnum.ROLE_INSTRUCTOR_MANAGER.getValue().equals(authority.getAuthority())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java
index bc17e345..9d168955 100644
--- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java
+++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationEvaluationApi.java
@@ -7,8 +7,8 @@ import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
-import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
+import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
@@ -16,6 +16,8 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
public interface ApplicationEvaluationApi {
@Operation(summary = "API to create or update ApplicationEvaluation",
diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/AppointmentApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AppointmentApi.java
new file mode 100644
index 00000000..5507492a
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AppointmentApi.java
@@ -0,0 +1,59 @@
+package net.gepafin.tendermanagement.web.rest.api;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import jakarta.servlet.http.HttpServletRequest;
+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.model.util.Response;
+import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+public interface AppointmentApi {
+
+ @Operation(summary = "API to check or create ndg.", 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 = "/application/{applicationId}/check-ndg", produces = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity> checkNdgForAppointment(HttpServletRequest request,
+ @Parameter(description = "The application id", required = true) @PathVariable(value = "applicationId", required = true) Long applicationId);
+
+ @Operation(summary = "API to create appointment.", 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) })) })
+ @PostMapping(value = "/application/{applicationId}", produces = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity> createAppointment(HttpServletRequest request,
+ @Parameter(description = "The application id", required = true) @PathVariable(value = "applicationId", required = true) Long applicationId,
+ @RequestBody CreateAppointmentRequest createAppointmentRequest);
+
+ @Operation(summary = "API to Upload document to external system.", 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) })) })
+ @PostMapping(value = "/document/{documentId}", produces = MediaType.APPLICATION_JSON_VALUE)
+ ResponseEntity> uploadDocumentToExternalSystem(HttpServletRequest request,
+ @Parameter(description = "The document id", required = true) @PathVariable(value = "documentId", required = true) Long documentId,
+ @RequestBody UploadDocToExternalSystemRequest docToExternalSystemRequest);
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java
index 1cfbb5c9..3910132c 100644
--- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java
+++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java
@@ -32,7 +32,7 @@ public interface AssignedApplicationsApi {
@ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) }))
})
@PostMapping(value = "/application/{applicationId}")
- @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')")
+ @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')|| hasRole('ROLE_INSTRUCTOR_MANAGER')")
public ResponseEntity> createAssignedApplications(
HttpServletRequest request,
@Parameter(description = "ID of the application", required = true) @PathVariable Long applicationId,
diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java
index be177bf9..b299ecc2 100644
--- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java
+++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationEvaluationApiController.java
@@ -3,12 +3,13 @@ package net.gepafin.tendermanagement.web.rest.api.impl;
import jakarta.servlet.http.HttpServletRequest;
import net.gepafin.tendermanagement.config.Translator;
import net.gepafin.tendermanagement.constants.GepafinConstant;
-import net.gepafin.tendermanagement.enums.ApplicationStatusForEvaluation;
import net.gepafin.tendermanagement.enums.UserActionContextEnum;
import net.gepafin.tendermanagement.enums.UserActionLogsEnum;
import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest;
+import net.gepafin.tendermanagement.model.request.EvaluationDocumentRequest;
import net.gepafin.tendermanagement.model.request.UserActionRequest;
import net.gepafin.tendermanagement.model.response.ApplicationEvaluationResponse;
+import net.gepafin.tendermanagement.model.response.EvaluationDocumentResponse;
import net.gepafin.tendermanagement.model.util.Response;
import net.gepafin.tendermanagement.service.ApplicationEvaluationService;
import net.gepafin.tendermanagement.util.LoggingUtil;
@@ -20,6 +21,8 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.util.List;
+
@RestController
@RequestMapping("${openapi.gepafin.base-path:/v1/applicationEvaluation}")
public class ApplicationEvaluationApiController implements ApplicationEvaluationApi {
diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AppointmentController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AppointmentController.java
new file mode 100644
index 00000000..9264aa3a
--- /dev/null
+++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AppointmentController.java
@@ -0,0 +1,81 @@
+package net.gepafin.tendermanagement.web.rest.api.impl;
+
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.extern.slf4j.Slf4j;
+import net.gepafin.tendermanagement.config.Translator;
+import net.gepafin.tendermanagement.constants.GepafinConstant;
+import net.gepafin.tendermanagement.enums.UserActionContextEnum;
+import net.gepafin.tendermanagement.enums.UserActionLogsEnum;
+import net.gepafin.tendermanagement.model.request.CreateAppointmentRequest;
+import net.gepafin.tendermanagement.model.request.UploadDocToExternalSystemRequest;
+import net.gepafin.tendermanagement.model.request.UserActionRequest;
+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.model.util.Response;
+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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${openapi.gepafin.base-path:/v1/appointment}")
+@Slf4j
+public class AppointmentController implements AppointmentApi {
+
+ @Autowired
+ private AppointmentService appointmentService;
+
+ @Autowired
+ private LoggingUtil loggingUtil;
+
+ @Override
+ public ResponseEntity> checkNdgForAppointment(HttpServletRequest request, Long applicationId) {
+
+ /** This code is responsible for creating user action logs for the "checking or creating ndg" operation. **/
+ loggingUtil.logUserAction(
+ UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CHECK_OR_CREATE_NDG_CODE).build());
+
+ NdgResponse appointmentLoginResponse = appointmentService.checkNdgForAppointment(request, applicationId);
+
+ return ResponseEntity.status(HttpStatus.OK).body(new Response<>(appointmentLoginResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.NDG_FETCH_SUCCESSFULLY)));
+ }
+
+ @Override
+ public ResponseEntity> createAppointment(HttpServletRequest request, Long applicationId,
+ CreateAppointmentRequest createAppointmentRequest) {
+
+ /** This code is responsible for creating user action logs for the "create appointment" operation. **/
+ loggingUtil.logUserAction(
+ UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.INSERT).actionContext(UserActionContextEnum.CREATE_APPOINTMENT).build());
+
+ AppointmentCreationResponse appointmentCreationResponse = appointmentService.createAppointmentForApplication(request, applicationId, createAppointmentRequest);
+
+ return ResponseEntity.status(HttpStatus.CREATED)
+ .body(new Response<>(appointmentCreationResponse, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPOINTMENT_CREATED)));
+ }
+
+ @Override
+ public ResponseEntity> uploadDocumentToExternalSystem(HttpServletRequest request, Long documentId,
+ UploadDocToExternalSystemRequest docToExternalSystemRequest) {
+
+ /** This code is responsible for creating user action logs for the "Upload document to external system" operation. **/
+ loggingUtil.logUserAction(
+ UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPLOAD).actionContext(UserActionContextEnum.UPLOAD_DOCUMENT_TO_EXTERNAL_SYSTEM).build());
+
+ DocumentUploadResponse documentUploadResponse = appointmentService.uploadDocToExternalSystem(request, documentId, docToExternalSystemRequest);
+
+ String message = GepafinConstant.DOCUMENT_UPLOADED_SUCCESSFULLY_TO_EXTERNAL_SYSTEM;
+ if(documentUploadResponse == null) {
+ message = GepafinConstant.DOCUMENT_UPLOADING_IN_PROGRESS;
+ }
+ return ResponseEntity.status(HttpStatus.OK)
+ .body(new Response<>(documentUploadResponse, Status.SUCCESS, Translator.toLocale(message)));
+
+ }
+}
diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java
index 9d42ab53..123a4620 100644
--- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java
+++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/DocumentApiController.java
@@ -47,7 +47,7 @@ DocumentApiController implements DocumentApi {
/** This code is responsible for creating user action logs for the "upload document for call or application" operation. **/
loggingUtil.logUserAction(UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.UPLOAD).actionContext(userActionContext).build());
- List responseBeans = documentService.uploadFile(files, sourceId, sourceType, fileType);
+ List responseBeans = documentService.uploadFile(httpServletRequest,files, sourceId, sourceType, fileType);
return ResponseEntity.status(HttpStatus.CREATED)
.body(new Response>(responseBeans, Status.SUCCESS, Translator.toLocale(GepafinConstant.FILES_UPLOADED_MSG)));
} catch (CustomValidationException ex) {
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 8fa5c7a6..f99634bc 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -15,3 +15,11 @@ gepafin_email=rinaldo.bonazzo@bflows.net
rinaldo_email=rinaldo.bonazzo@bflows.net
carlo_email=test@test.test
default.hub.uuid=p4lk3bcx1RStqTaIVVbXs
+
+#Login to Odessa, Appointment Creation, Upload document Configuration
+appointment.base.url=https://demo.galileonetwork.it/gateway/rest
+appointment.portal.user=UtenzaAPIPortal@621
+appointment.portal.password=u13nzaAP1P0rtal
+appointment.portal.source=GEPAFINPORTAL
+appointment.portal.context=GEPAFINPORTAL
+flagDaFirmare=false
\ No newline at end of file
diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties
index 76aca344..37bcabad 100644
--- a/src/main/resources/application-local.properties
+++ b/src/main/resources/application-local.properties
@@ -13,4 +13,11 @@ default_System_Receiver_Email=test@test.test
gepafin_email=test@test.test
rinaldo_email=test@test.test
carlo_email=test@test.test
-default.hub.uuid=p4lk3bcx1RStqTaIVVbXs
\ No newline at end of file
+default.hub.uuid=p4lk3bcx1RStqTaIVVbXs
+
+appointment.base.url=https://demo.galileonetwork.it/gateway/rest
+appointment.portal.user=UtenzaAPIPortal@621
+appointment.portal.password=u13nzaAP1P0rtal
+appointment.portal.source=GEPAFINPORTAL
+appointment.portal.context=GEPAFINPORTAL
+flagDaFirmare=false
\ No newline at end of file
diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties
index b3704a3d..31a7e7b4 100644
--- a/src/main/resources/application-production.properties
+++ b/src/main/resources/application-production.properties
@@ -22,3 +22,11 @@ rinaldo_email=rinaldo.bonazzo@bflows.net
carlo_email=carlo.mancosu@bflows.net
default.hub.uuid=p4lk3bcx1RStqTaIVVbXs
# TEST DEPLOY Configuration
+
+#Login to Odessa, Appointment Creation, Upload document Configuration
+appointment.base.url=https://demo.galileonetwork.it/gateway/rest
+appointment.portal.user=UtenzaAPIPortal@621
+appointment.portal.password=u13nzaAP1P0rtal
+appointment.portal.source=GEPAFINPORTAL
+appointment.portal.context=GEPAFINPORTAL
+flagDaFirmare=false
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index fb109ba7..60f61aec 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -65,3 +65,6 @@ default.email.signature=Gepafin S.p.a
default.hub.pdf.banner=https://mementoresources.s3.amazonaws.com/gepafin/staging/template/gepafin-logo.jpg
+#feign client config
+spring.cloud.openfeign.client.config.default.connectTimeout=300000
+spring.cloud.openfeign.client.config.default.readTimeout=300000
\ No newline at end of file
diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml
index 9c061c37..6eee497f 100644
--- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml
+++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml
@@ -1972,5 +1972,97 @@
path="db/dump/update_system_email_template_for_updating_amendment_mail_notification_mail_04_12_2024_1.sql"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties
index 68d7a49b..a644c61c 100644
--- a/src/main/resources/message_en.properties
+++ b/src/main/resources/message_en.properties
@@ -314,4 +314,25 @@ company.id.required.for.preferred.call=Company ID is required when requesting on
response.days.not.null=Response days should not be null and greater than zero.
application.cannot.approved.or.rejected=Application cannot be approved and rejected because amendment is active.
-atleast.one.id.required=At least one of companyId or applicationId must be provided
\ No newline at end of file
+atleast.one.id.required=At least one of companyId or applicationId must be provided
+
+#Appointment flow messages
+ndg.generated = NDG Generated.
+ndg.available = NDG Available.
+ndg.generation.in.progress = NDG generation is in progress.
+ndg.fetch.successfully = NDG fetched successfully.
+appointment.already.created = Appointment Already Created.
+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.
+document.uploaded.successfully.to.external.system = Document uploaded successfully to external system.
+error.in.uploading.document.check.input = Error in uploading document check input data or try again.
+document.already.uploaded = Document already uploaded.
+document.not.uploaded.to.external.system.please.try.again = Document not uploaded to external system, please try again.
+ndg.not.found.or.not.matched = The provided NDG does not match the application NDG, or the NDG has not been generated.
+ndg.generation.is.only.for.gepafin = NDG generation is only available for GEPAFIN Hub.
+appointment.creation.is.only.for.gepafin = Appointment creation is only allowed 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.
+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.
diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties
index 30ffc1ac..e350546e 100644
--- a/src/main/resources/message_it.properties
+++ b/src/main/resources/message_it.properties
@@ -197,8 +197,6 @@ invalid.vatnumber=Numero di partita IVA non valido.
vatnumber.mandatory=Il numero di partita IVA � obbligatorio.
vatnumber.already.exists=Il numero di partita IVA esiste gi�.
invalid.email=Email non valida.
-company.id.mandatory=L'ID dell'azienda � obbligatorio.
-user.already.connected.to.company=L'utente � gi� collegato a questa azienda.
validation.error.missing.firstName=Il nome � obbligatorio.
validation.error.missing.lastName=Il cognome � obbligatorio.
validation.error.missing.codiceFiscale=Il Codice Fiscale � obbligatorio.
@@ -306,5 +304,25 @@ beneficiary.call.duplicate = Una chiamata preferita con questo ID di chiamata e
user.must.be.associated.with.company.to.create.application=Devi essere associato a un'azienda per poter presentare domanda per questa applicazione.
company.id.required.for.preferred.call=ID azienda obbligatorio quando si richiedono solo chiamate preferite.
response.days.not.null=I giorni di risposta non devono essere nulli e maggiori di zero.
-application.cannot.approved.or.rejected=La domanda non può essere approvata o rifiutata perché l'emendamento è attivo.
-atleast.one.id.required=Almeno uno tra companyId o applicationId deve essere fornito.
\ No newline at end of file
+application.cannot.approved.or.rejected=La domanda non pu� essere approvata o rifiutata perch� l'emendamento � attivo.
+atleast.one.id.required=Almeno uno tra companyId o applicationId deve essere fornito.
+
+#Appointment flow messages
+ndg.available = NDG disponibile.
+ndg.generation.in.progress = La generazione NDG ? in corso.
+ndg.fetch.successfully = NDG recuperato con successo.
+appointment.already.created = Appuntamento gi? creato.
+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.
+document.uploaded.successfully.to.external.system = Documento caricato con successo nel sistema esterno.
+error.in.uploading.document.check.input = Errore nel caricamento del documento. Controlla i dati inseriti o riprova.
+document.already.uploaded = Documento gi? caricato.
+document.not.uploaded.to.external.system.please.try.again = Documento non caricato nel sistema esterno, riprova.
+ndg.not.found.or.not.matched = L'NDG fornito non corrisponde all'NDG dell'applicazione o non ? stato generato.
+ndg.generation.is.only.for.gepafin = La generazione dell'NDG ? disponibile solo per GEPAFIN.
+appointment.creation.is.only.for.gepafin = La creazione degli appuntamenti ? consentita solo per 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.
+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.