diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index f0ebabeb..bbbeb1eb 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -341,6 +341,7 @@ public class GepafinConstant { 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"; //Notification public static final String COMMON_SINGLE_CHANNEL_PREFIX = "/topic/notifications_user_"; @@ -354,4 +355,3 @@ public class GepafinConstant { public static final String USER_WITH_COMPANY_NOT_FOUND = "user.with.company.not.found"; } - diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index e6ccd62b..86a99f45 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -105,6 +105,12 @@ public class ApplicationAmendmentRequestDao { @Autowired private AssignedApplicationsDao assignedApplicationsDao; + @Autowired + private ApplicationEvaluationDao applicationEvaluationDao; + + @Autowired + private DocumentRepository documentRepository; + @Autowired private NotificationDao notificationDao; @@ -115,8 +121,26 @@ public class ApplicationAmendmentRequestDao { 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) @@ -141,11 +165,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); @@ -243,6 +274,7 @@ public class ApplicationAmendmentRequestDao { AmendmentFormField formField = new AmendmentFormField(); formField.setFieldId(amendmentFormFieldRequest.getFieldId()); formField.setFieldValue(null); + formField.setLabel(amendmentFormFieldRequest.getLabel()); return formField; }) .collect(Collectors.toList()); @@ -267,7 +299,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(); @@ -311,6 +343,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); @@ -326,16 +377,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()); @@ -509,6 +614,20 @@ public class ApplicationAmendmentRequestDao { log.info("Updating application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); + Boolean isBeneficiary=false; + if (Boolean.FALSE.equals(validator.checkIsBeneficiary())) { + validator.validatePreInstructor(request, existingApplicationAmendment.getApplicationEvaluationEntity().getUserId()); + isBeneficiary=false; + } else { + validator.validateUserId(request, existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getUserId()); + isBeneficiary=true; + } + if(Boolean.TRUE.equals(isBeneficiary) && existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue())){ + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); + } + if(Boolean.FALSE.equals(isBeneficiary) && existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())){ + throw new CustomValidationException(Status.VALIDATION_ERROR,Translator.toLocale(GepafinConstant.PERMISSION_DENIED)); + } ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); setIfUpdated(existingApplicationAmendment::getNote, existingApplicationAmendment::setNote, updateRequest.getNote()); @@ -521,14 +640,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); @@ -595,13 +716,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()); @@ -610,7 +731,8 @@ public class ApplicationAmendmentRequestDao { if (!existingDocumentIds.isEmpty()) { existingDocumentIds.forEach(this::softDeleteDocument); amendmentFormField.setFieldValue(null); - setIsUploadedBy(amendmentFormField); + amendmentFormField.setValid(applicationFormFieldRequest.getValid()); +// setIsUploadedBy(amendmentFormField); } return; } @@ -624,11 +746,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) @@ -639,14 +762,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) { @@ -959,7 +1082,7 @@ public class ApplicationAmendmentRequestDao { log.info("Updating application amendment with status: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); - if (Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())) || Boolean.TRUE.equals(statusTypeEnum.equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED))) { + if (Boolean.TRUE.equals(existingApplicationAmendment.getStatus().equals(ApplicationAmendmentRequestEnum.AWAITING.getValue())) && Boolean.TRUE.equals(statusTypeEnum.equals(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED))) { existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()); existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestRepository.save(existingApplicationAmendment); @@ -1043,12 +1166,6 @@ public class ApplicationAmendmentRequestDao { } - public List getApplicationAmendmentRequestEntitiesByApplicationEvaluationId(Long applicationEvaluationId){ - List applicationAmendmentRequestEntities=new ArrayList<>(); - applicationAmendmentRequestEntities=applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(applicationEvaluationId,ApplicationAmendmentRequestEnum.CLOSE.getValue()); - return applicationAmendmentRequestEntities; - } - private void softDeleteDocument(Long documentId) { documentService.deleteFile(documentId); } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index c687fd67..04db6f06 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -469,7 +469,7 @@ public class ApplicationDao { if (applicationFormFieldEntity1.getFieldId().equals(applicationFormFieldRequestBean.getFieldId())) { applicationFormFieldEntity = applicationFormFieldEntity1; oldApplicationFormFieldData = Utils.getClonedEntityForData(applicationFormFieldEntity); - if (applicationFormEntity.getForm().getId().equals(applicationFormEntity.getApplication().getCall().getInitialForm())) { + if (applicationFormEntity.getForm().getId().equals(applicationFormEntity.getApplication().getCall().getInitialForm()) && checkIfRequestFieldIsDifferent(applicationFormFieldEntity1, applicationFormFieldRequestBean)) { validateRequiredFields(applicationFormEntity.getForm(), applicationFormEntity.getApplication(), applicationFormFieldRequestBean.getFieldId()); } actionType = VersionActionTypeEnum.UPDATE; @@ -505,7 +505,30 @@ public class ApplicationDao { return applicationFormField; } - void updateDocumentDeletionStatus(ApplicationFormFieldEntity applicationFormFieldEntity, ApplicationFormFieldRequestBean applicationFormFieldRequestBean, FormEntity formEntity, List newDocumentIds, + private Boolean checkIfRequestFieldIsDifferent(ApplicationFormFieldEntity applicationFormFieldEntity, + ApplicationFormFieldRequestBean applicationFormFieldRequestBean) { + + // Retrieve the field values from both objects + String entityFieldValue = applicationFormFieldEntity.getFieldValue(); + Object requestFieldValue = applicationFormFieldRequestBean.getFieldValue(); + + // Check if both are null + if (entityFieldValue == null && requestFieldValue == null) { + return false; // No difference if both are null + } + + // Compare values + Boolean check = !Objects.equals(entityFieldValue, requestFieldValue); + + // Additional comparison if both are non-null + if (Boolean.TRUE.equals(check) && entityFieldValue != null && requestFieldValue != null) { + check = !entityFieldValue.equals(requestFieldValue.toString()); + } + + return check; + } + + void updateDocumentDeletionStatus(ApplicationFormFieldEntity applicationFormFieldEntity, ApplicationFormFieldRequestBean applicationFormFieldRequestBean, FormEntity formEntity, List newDocumentIds, List preInstructorDocumentId,boolean isPreInstructor) { if (newDocumentIds == null) { newDocumentIds = Collections.emptyList(); @@ -791,18 +814,18 @@ public class ApplicationDao { UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyEntity.getId()); // call = callService.validatePublishedCall(call.getId()); - checkIfApplicationExists(call, userWithCompanyEntity, userEntity); +// checkIfApplicationExists(call, userWithCompanyEntity, userEntity); ApplicationEntity applicationEntity = createApplicationEntity(userEntity, call, userWithCompanyEntity); applicationEntity.setComments(applicationRequest.getComments()); applicationEntity = saveApplicationEntity(applicationEntity); return getApplicationResponse(applicationEntity); } - public void checkIfApplicationExists(CallEntity call, UserWithCompanyEntity userWithCompanyEntity, UserEntity userEntity){ - Optional applicationEntity=applicationRepository.findByUserIdAndUserWithCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), userWithCompanyEntity.getId(),call.getId()); - if(applicationEntity.isPresent()){ - throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); - } - } +// public void checkIfApplicationExists(CallEntity call, UserWithCompanyEntity userWithCompanyEntity, UserEntity userEntity){ +// Optional applicationEntity=applicationRepository.findByUserIdAndUserWithCompanyIdAndCallIdAndIsDeletedFalse(userEntity.getId(), userWithCompanyEntity.getId(),call.getId()); +// if(applicationEntity.isPresent()){ +// throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_EXISTS)); +// } +// } public ApplicationResponse updateApplicationStatus(HttpServletRequest request, Long applicationId, ApplicationStatusTypeEnum status) { @@ -823,7 +846,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())); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 6c5e46c7..87b63c3b 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 { @@ -99,6 +101,15 @@ public class ApplicationEvaluationDao { @Autowired private UserRepository userRepository; + @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(); @@ -134,16 +145,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()); @@ -491,9 +589,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()); @@ -509,6 +613,18 @@ public class ApplicationEvaluationDao { } 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); @@ -524,22 +640,212 @@ 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->{ + ApplicationAmendmentRequestEntity oldEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); + updateAmendment(applicationAmendmentRequestEntity, amendmentFormFieldsMap.get(applicationAmendmentRequestEntity.getId())); + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().actionType(VersionActionTypeEnum.UPDATE).oldData(oldEntity).newData(applicationAmendmentRequestEntity).build()); + }); + 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<>()); @@ -659,11 +965,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) { @@ -675,11 +1022,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) { @@ -777,7 +1132,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); } } @@ -906,7 +1261,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()); @@ -1425,9 +1780,14 @@ public class ApplicationEvaluationDao { ApplicationEvaluationEntity oldApplicationEvaluation = Utils.getClonedEntityForData(existingEntity); AssignedApplicationsEntity oldAssignedApplication = Utils.getClonedEntityForData(assignedApplicationsEntity); + List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(existingEntity.getId(),List.of(ApplicationAmendmentRequestEnum.AWAITING.getValue(),ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.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()); + existingEntity.setClosingDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); assignedApplicationsEntity.setStatus(AssignedApplicationEnum.CLOSE.getValue()); } entity = applicationEvaluationRepository.save(existingEntity); @@ -1443,11 +1803,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); } @@ -1470,5 +1825,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 index 49a672a8..a45b142d 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -785,8 +785,9 @@ public class AppointmentDao { 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)); +// throw new CustomValidationException(Status.SUCCESS, Translator.toLocale(GepafinConstant.DOCUMENT_UPLOADING_IN_PROGRESS)); } private void uploadDocumentToExternalSystemSync(Long documentId, UploadDocToExternalSystemRequest docToExternalSystemRequest) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index e820297d..cc281df7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -15,6 +15,7 @@ import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; +import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; @@ -226,7 +227,7 @@ public class AssignedApplicationsDao { public AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, - Long id, AssignedApplicationsRequest updateRequest) { + Long id, UpdateAssignedApplicationRequest updateRequest) { UserEntity updatedByUser = validator.validateUser(request); log.info("Updating assigned application with ID: {}", id); AssignedApplicationsEntity existingAssignment = validateAssignedApplication(id); @@ -237,7 +238,9 @@ public class AssignedApplicationsDao { setIfUpdated(existingAssignment::getNote, existingAssignment::setNote, updateRequest.getNote()); setIfUpdated(existingAssignment::getStatus, existingAssignment::setStatus, updateRequest.getStatus().name()); setIfUpdated(existingAssignment::getAssignedBy, existingAssignment::setAssignedBy, updatedByUser.getId()); - + setIfUpdated(existingAssignment::getUserId, existingAssignment::setUserId, updateRequest.getUserId()); + Optional entityOptional = applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse(id); + entityOptional.ifPresent(applicationEvaluationEntity -> setIfUpdated(applicationEvaluationEntity::getUserId, applicationEvaluationEntity::setUserId, updateRequest.getUserId())); existingAssignment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); AssignedApplicationsEntity updatedAssignment = saveAssignedApplication(existingAssignment, oldAssignedApplicationEntity, VersionActionTypeEnum.UPDATE); 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/dao/UserDao.java b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java index da5c6f07..7e35957b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/UserDao.java @@ -448,12 +448,14 @@ public class UserDao { return authService.validateNewUserToken(token); } - public List getAllUsers(UserEntity user, Long roleId) { + public List getAllUsers(UserEntity user, List roleIds) { List users; - if (roleId != null) { - log.info("Fetching users by role ID: {}", roleId); - RoleEntity roleEntity=roleService.validateRole(roleId); - users = userRepository.findByRoleEntityIdAndHubId(roleEntity.getId(), user.getHub().getId()); + if (roleIds != null) { + log.info("Fetching users by role ID: {}", roleIds); + List roleEntities = roleIds.stream() + .map(roleService::validateRole) // Assuming `validateRole` takes an ID and returns a RoleEntity + .collect(Collectors.toList()); + users = userRepository.findByRoleEntityIdInAndHubId(roleIds, user.getHub().getId()); } else { log.info("Fetching all users"); users = userRepository.findByHubId(user.getHub().getId()); @@ -462,7 +464,7 @@ public class UserDao { .map(this::convertUserEntityToUserResponse) .collect(Collectors.toList()); - log.info("Total users found with role ID {}: {}", roleId, userResponseBeans.size()); + log.info("Total users found with role ID {}: {}", roleIds, userResponseBeans.size()); return userResponseBeans; } 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/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index e33881b1..15e3d3d7 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,8 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @Column(name = "STOP_DATE_TIME") private LocalDateTime stopDateTime; + + @Column(name = "CLOSING_DATE") + private LocalDateTime closingDate; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java index d15a65e6..08bfd623 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/DocumentEntity.java @@ -32,4 +32,7 @@ public class DocumentEntity extends BaseEntity{ @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/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/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 94fabe89..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"), 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/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/UpdateAssignedApplicationRequest.java b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateAssignedApplicationRequest.java new file mode 100644 index 00000000..ac9a176b --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/request/UpdateAssignedApplicationRequest.java @@ -0,0 +1,10 @@ +package net.gepafin.tendermanagement.model.request; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; +@Data +public class UpdateAssignedApplicationRequest { + private String note; + private AssignedApplicationEnum status; + private Long userId; +} 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 ca3eaa71..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; 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/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index 4a2e3252..68133efb 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 findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(Long id, String status); + "AND amr.status IN (:statuses)") + List findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(Long id, List statuses); @Query("SELECT a FROM ApplicationAmendmentRequestEntity a " + "WHERE a.isDeleted = false " + diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java index 4e4069f3..f9a7b0ac 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java @@ -1,5 +1,6 @@ package net.gepafin.tendermanagement.repositories; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -21,6 +22,12 @@ public interface ApplicationEvaluationRepository 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 { boolean existsByEmailIgnoreCaseAndHubUniqueUuid(String email, String hubUuid); - List findByRoleEntityIdAndHubId(Long roleId, Long hubId); + List findByRoleEntityIdInAndHubId(List roleIds, Long hubId); List findByHubId(Long hubId); diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java index 1b6ed976..91cfaf78 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -1,41 +1,42 @@ package net.gepafin.tendermanagement.scheduler; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import net.gepafin.tendermanagement.dao.NotificationDao; -import net.gepafin.tendermanagement.entities.ApplicationEntity; -import net.gepafin.tendermanagement.enums.NotificationTypeEnum; -import net.gepafin.tendermanagement.model.request.NotificationReq; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; - import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; -import net.gepafin.tendermanagement.dao.EmailNotificationDao; +import net.gepafin.tendermanagement.dao.NotificationDao; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +import net.gepafin.tendermanagement.entities.ApplicationEntity; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; +import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; +import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; 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.ApplicationAmendmentRequestRepository; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import net.gepafin.tendermanagement.repositories.ApplicationRepository; +import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; +import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; @Component public class ApplicationAmendmentScheduler { @@ -46,8 +47,6 @@ public class ApplicationAmendmentScheduler { @Autowired private ApplicationAmendmentRequestRepository applicationAmendmentRepository; - @Autowired - private EmailNotificationDao emailNotificationDao; @Autowired private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; @@ -58,6 +57,18 @@ public class ApplicationAmendmentScheduler { @Autowired private NotificationDao notificationDao; + @Autowired + private AssignedApplicationsRepository assignedApplicationsRepository; + + @Autowired + private ApplicationService applicationService; + + @Autowired + private ApplicationRepository applicationRepository; + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + private static final Logger log = LoggerFactory.getLogger(ApplicationAmendmentScheduler.class); @Scheduled(cron = "0 0 1 * * ?") @@ -88,7 +99,7 @@ public class ApplicationAmendmentScheduler { amendmentRequests.forEach(request -> { try { ApplicationAmendmentRequestEntity oldAmendmentRequestEntity = Utils.getClonedEntityForData(request); - request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + request.setStatus(ApplicationAmendmentRequestEnum.EXPIRED.getValue()); ApplicationEntity application=oldAmendmentRequestEntity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication(); request = applicationAmendmentRepository.save(request); Map placeHolders=notificationDao.sendNotificationToBeneficiary(application,NotificationTypeEnum.AMENDMENT_EXPIRED); @@ -96,8 +107,8 @@ public class ApplicationAmendmentScheduler { /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendmentRequestEntity).newData(request).build()); - emailNotificationDao.sendApplicationFailureNotificationEmail(request); - log.info("Updated status to CLOSED for ApplicationAmendmentRequest with ID: {}", request.getId()); +// emailNotificationDao.sendApplicationFailureNotificationEmail(request); + log.info("Updated status to EXPIRED for ApplicationAmendmentRequest with ID: {}", request.getId()); } catch (Exception e) { log.error("Error expiring ApplicationAmendmentRequest with ID {}: {}", request.getId(), e.getMessage(), e); @@ -115,6 +126,16 @@ public class ApplicationAmendmentScheduler { evaluationsWithoutActiveAmendmentList.forEach(evaluation -> { try { applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(evaluation); + + updateEvaluationStatus(evaluation); + + // Update AssignedApplicationsEntity status + updateAssignedApplicationStatus(evaluation.getAssignedApplicationsEntity()); + + // Update ApplicationEntity status + updateApplicationStatus(evaluation.getAssignedApplicationsEntity().getApplication()); + + log.info("Updated EndDate and suspension days for ApplicationEvaluation with ID: {}", evaluation.getId()); } catch (Exception e) { @@ -130,4 +151,35 @@ public class ApplicationAmendmentScheduler { } + public void updateAssignedApplicationStatus(AssignedApplicationsEntity assignedApplicationsEntity){ + AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplicationsEntity); + assignedApplicationsEntity.setStatus(AssignedApplicationEnum.OPEN.getValue()); + assignedApplicationsRepository.save(assignedApplicationsEntity); + log.info("Updated status to OPEN for Assigned Application with ID: {}", assignedApplicationsEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Assigned Application status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplicationsEntity).build()); + + } + + public void updateApplicationStatus(ApplicationEntity applicationEntity){ + ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); + applicationEntity.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); + applicationRepository.save(applicationEntity); + log.info("Updated status to EVALUATION for Application with ID: {}",applicationEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Application Status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); + + } + public void updateEvaluationStatus(ApplicationEvaluationEntity applicationEvaluationEntity){ + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); + applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); + applicationEvaluationRepository.save(applicationEvaluationEntity); + log.info("Updated status to OPEN for ApplicationEvaluation with ID: {}", applicationEvaluationEntity.getId()); + + /** This code is responsible for adding a version history log for the "Update Application Status" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluationEntity).build()); + + } } 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/AssignedApplicationsService.java b/src/main/java/net/gepafin/tendermanagement/service/AssignedApplicationsService.java index f1670687..1a73c674 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AssignedApplicationsService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AssignedApplicationsService.java @@ -3,6 +3,7 @@ package net.gepafin.tendermanagement.service; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; +import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import java.util.List; @@ -15,7 +16,7 @@ public interface AssignedApplicationsService { void deleteApplication(HttpServletRequest request, Long id); List getAllAssignedApplications(HttpServletRequest request, Long userId); - AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, AssignedApplicationsRequest assignedApplicationsRequest); + AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, UpdateAssignedApplicationRequest assignedApplicationsRequest); AssignedApplicationsResponse getAssignedApplicationById(HttpServletRequest request, Long id); AssignedApplicationsEntity validateAssignedApplication(Long assignedApplicationId); } 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/UserService.java b/src/main/java/net/gepafin/tendermanagement/service/UserService.java index 21109a5e..4808b00e 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/UserService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/UserService.java @@ -45,6 +45,6 @@ public interface UserService { UserEntity getUserByBeneficiaryId(Long beneficiaryId); public UserEntity getUserEntityById(Long userId); - List getAllUsers(HttpServletRequest request, Long roleId); + List getAllUsers(HttpServletRequest request, List roleIds); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java index 3af50f6c..8221117a 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AmazonS3ServiceImpl.java @@ -30,6 +30,8 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -118,12 +120,15 @@ public class AmazonS3ServiceImpl implements AmazonS3Service { public InputStream getFile(String s3Folder, String filePath) { try { String fileName = Utils.extractFileName(filePath); - String path = s3Folder + "/" + fileName; + // Decode the file name to handle special characters like '+' correctly + String decodedFileName = URLDecoder.decode(fileName, StandardCharsets.UTF_8.toString()); + + String path = s3Folder + "/" + decodedFileName; GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, path); S3Object s3Object = amazonS3.getObject(getObjectRequest); log.info("File fetched successfully from Amazon S3: {}", fileName); return s3Object.getObjectContent(); - } catch (AmazonS3Exception e) { + } catch (Exception e) { log.error("Error occurred while getting file from Amazon S3: {}", e); throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.GET_ERROR_S3)); diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java index 7329c5c3..e2615a71 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java @@ -91,13 +91,6 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm @Override @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse updateApplicationAmendment(HttpServletRequest request, Long id, ApplicationAmendmentRequestBean applicationAmendmentRequestBean) { - ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(id); - - if (Boolean.FALSE.equals(validator.checkIsBeneficiary())) { - validator.validatePreInstructor(request, amendment.getApplicationEvaluationEntity().getUserId()); - } else { - validator.validateUserId(request, amendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication().getUserId()); - } return applicationAmendmentRequestDao.updateApplicationAmendment(id,applicationAmendmentRequestBean); } 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/AssignedApplicationsServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AssignedApplicationsServiceImpl.java index 154e342a..c820d929 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AssignedApplicationsServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AssignedApplicationsServiceImpl.java @@ -5,6 +5,7 @@ import net.gepafin.tendermanagement.dao.AssignedApplicationsDao; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; +import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.service.AssignedApplicationsService; import net.gepafin.tendermanagement.util.Validator; @@ -45,7 +46,7 @@ public class AssignedApplicationsServiceImpl implements AssignedApplicationsServ @Override @Transactional(rollbackFor = Exception.class) - public AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, AssignedApplicationsRequest updatedAssignedApplicationRequest) { + public AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, UpdateAssignedApplicationRequest updatedAssignedApplicationRequest) { return assignedApplicationsDao.updateAssignedApplication(request, id, updatedAssignedApplicationRequest); } 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/service/impl/UserServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java index 9f95b830..c38b2c8c 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/UserServiceImpl.java @@ -126,8 +126,8 @@ public class UserServiceImpl implements UserService { } @Override @Transactional(readOnly = true) - public List getAllUsers(HttpServletRequest request, Long roleId) { + public List getAllUsers(HttpServletRequest request, List roleIds) { UserEntity user=validator.validateUser(request); - return userDao.getAllUsers(user, roleId); + return userDao.getAllUsers(user, roleIds); } } \ No newline at end of file diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 486ddd02..b126e6dd 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -664,7 +664,29 @@ public class Utils { } 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; + } + } + public static String createChannelForUserAndCompany(Long userId, Long companyId) { return GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId + GepafinConstant.COMPANY_PREFIX + companyId; } 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/AssignedApplicationsApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java index 1cfbb5c9..144a20f4 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 @@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; +import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; @@ -32,7 +33,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, @@ -50,7 +51,7 @@ public interface AssignedApplicationsApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @DeleteMapping(value = "/{id}") - @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')|| hasRole('ROLE_INSTRUCTOR_MANAGER')") ResponseEntity> deleteAssignedApplication(HttpServletRequest request, @Parameter(description = "The assigned application id", required = true) @PathVariable("id") Long id); @@ -78,10 +79,10 @@ public interface AssignedApplicationsApi { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PutMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) - @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')|| hasRole('ROLE_INSTRUCTOR_MANAGER')") public ResponseEntity> updateAssignedApplication(HttpServletRequest request, @Parameter(description = "The Assigned Application id", required = true) @PathVariable("id") Long id, - @Parameter(description = "Assigned Application request object", required = true) @Valid @RequestBody AssignedApplicationsRequest assignedApplicationsRequest); + @Parameter(description = "Assigned Application request object", required = true) @Valid @RequestBody UpdateAssignedApplicationRequest assignedApplicationsRequest); @Operation(summary = "Api to get an assigned application by id", responses = { diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java index c7b8e530..86122344 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/UserApi.java @@ -234,9 +234,9 @@ public interface UserApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE)}))}) @RequestMapping(value = "", produces = {"application/json"}, method = RequestMethod.GET) - @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')") + @PreAuthorize("hasRole('ROLE_SUPER_ADMIN')|| hasRole('ROLE_INSTRUCTOR_MANAGER')") ResponseEntity>> getAllUsers(HttpServletRequest request, - @Parameter( required = false)@RequestParam(value ="roleId", required = false) Long roleId); + @Parameter( required = false)@RequestParam(value ="roleIds", required = false) List roleIds); @RequestMapping("favicon.ico") 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 index ca55e55f..9264aa3a 100644 --- 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 @@ -69,8 +69,13 @@ public class AppointmentController implements AppointmentApi { 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(GepafinConstant.DOCUMENT_UPLOADED_SUCCESSFULLY_TO_EXTERNAL_SYSTEM))); + .body(new Response<>(documentUploadResponse, Status.SUCCESS, Translator.toLocale(message))); } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java index 7f22337a..78cc47dd 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java @@ -7,6 +7,7 @@ import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; +import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.model.util.Response; @@ -66,7 +67,7 @@ public class AssignedApplicationsController implements AssignedApplicationsApi { } @Override - public ResponseEntity> updateAssignedApplication(HttpServletRequest request, Long id, AssignedApplicationsRequest updateAssignedApplicationRequest) { + public ResponseEntity> updateAssignedApplication(HttpServletRequest request, Long id, UpdateAssignedApplicationRequest updateAssignedApplicationRequest) { log.info("Update Assigned Application"); /** This code is responsible for "Updating Assigned Applications details" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.UPDATE) 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/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java index 7ff12c2a..22232b57 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/UserApiController.java @@ -216,14 +216,14 @@ public class UserApiController implements UserApi { } @Override - public ResponseEntity>> getAllUsers(HttpServletRequest request, Long roleId) { + public ResponseEntity>> getAllUsers(HttpServletRequest request, List roleIds) { - log.info("Get all Users by Role ID - Role ID: {}", roleId); + log.info("Get all Users by Role ID - Role ID: {}", roleIds); /** This code is responsible for creating user action logs for the "Get all users by role" operation. **/ loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW).actionContext(UserActionContextEnum.GET_ALL_USERS_BY_ROLE).build()); - List users = userService.getAllUsers(request, roleId); + List users = userService.getAllUsers(request, roleIds); return ResponseEntity.status(HttpStatus.OK).body(new Response<>(users, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_USERS_SUCCESS_MSG))); } 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 816716ad..0fdebf9e 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 @@ -1991,6 +1991,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index a1a01272..290f40af 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -335,6 +335,7 @@ upload.document.is.only.for.gepafin = Document cant be uploaded, this is only av 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. #notification messsages notification.already.in.state=Notification is already in provided status. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 03cf99d7..f41e4f1c 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -2,14 +2,14 @@ user.created.success=Utente creato con successo. user.updated.success=Utente aggiornato con successo. user.deleted.success=Utente eliminato con successo. user.not.found=Utente non trovato. -create_user_error_msg=Si � verificato un errore durante la creazione dell'utente. -update_user_error_msg=Si � verificato un errore durante l'aggiornamento dell'utente. -delete_user_error_msg=Si � verificato un errore durante l'eliminazione dell'utente. +create_user_error_msg=Si ? verificato un errore durante la creazione dell'utente. +update_user_error_msg=Si ? verificato un errore durante l'aggiornamento dell'utente. +delete_user_error_msg=Si ? verificato un errore durante l'eliminazione dell'utente. get_user_success_msg=Utente recuperato con successo. -get_user_error_msg=Si � verificato un errore durante il recupero dell'utente. +get_user_error_msg=Si ? verificato un errore durante il recupero dell'utente. user.not.active=Utente non attivo. Si prega di contattare il supporto. -user.already.exist.msg=L'utente esiste gi� per questo codice fiscale. -validate.email=L'email � obbligatoria e deve essere nel formato corretto. Si prega di verificare e riprovare. +user.already.exist.msg=L'utente esiste gi? per questo codice fiscale. +validate.email=L'email ? obbligatoria e deve essere nel formato corretto. Si prega di verificare e riprovare. validate.password=La password e confPassword sono obbligatorie. Verifica e riprova. # Role-related messages role.created.success=Ruolo creato con successo. @@ -20,7 +20,7 @@ create.role.error=Errore durante la creazione del ruolo. update.role.error=Errore durante l'aggiornamento del ruolo. role.fetch.success=Ruolo recuperato con successo. delete.role.error=Errore durante l'eliminazione del ruolo. -role.id.mandatory=L'ID del ruolo � obbligatorio. +role.id.mandatory=L'ID del ruolo ? obbligatorio. # Region-related messages region.created.success=Regione creata con successo. @@ -35,42 +35,42 @@ password.doesnt.match=La password e la conferma della password non corrispondono #call related messages user.not.exist=L'utente non esiste. region.not.found=Regione non trovata. -user.id.not.null=L'ID utente non pu� essere nullo. -question.not.empty=La domanda non pu� essere vuota. -name.not.empty=Il nome non pu� essere vuoto. -type.not.empty=Il tipo non pu� essere vuoto. -region.not.null=L'ID regione non pu� essere nullo. +user.id.not.null=L'ID utente non pu? essere nullo. +question.not.empty=La domanda non pu? essere vuota. +name.not.empty=Il nome non pu? essere vuoto. +type.not.empty=Il tipo non pu? essere vuoto. +region.not.null=L'ID regione non pu? essere nullo. amount.greater.than.zero=L'importo del finanziamento deve essere maggiore di zero. -look.up.data.not.valid=L'entit� dati di ricerca non � valida. +look.up.data.not.valid=L'entit? dati di ricerca non ? valida. files.uploaded=File caricati correttamente. call.created.successfully=Chiamata creata correttamente. file.deleted.successfully=File eliminato con successo. document.not.found=Documento non trovato. document.id.not.found=ID documento non trovato. call.invalid.date=Data di inizio o fine non valida. -call.id.not.null=L'ID della chiamata non pu� essere nullo. +call.id.not.null=L'ID della chiamata non pu? essere nullo. call.update.successfully=Chiamata aggiornata con successo. call.fetch.success=Dettagli della chiamata recuperati con successo. call.not.found=Chiamata non trovata. -score.not.null=Il punteggio non pu� essere nullo o zero. -field.not.null={0} non pu� essere nullo. -field.not.empty=la {0} non pu� essere vuota. -update_call_status_success_msg=Lo stato della chiamata � stato aggiornato con successo. -status.same.error=Lo stato � gi� impostato. -invalid.status.change.from.draft=Lo stato non pu� essere cambiato in READY_TO_PUBLISH o PUBLISH da DRAFT. -status.cannot.be.changed=Lo stato non pu� essere cambiato. -published.call.not.update=Il bando pubblicato non pu� essere aggiornato. -invalid.status.change.from.publish=Lo stato non pu� essere modificato in READY_TO_PUBLISH o DRAFT da PUBLISH. +score.not.null=Il punteggio non pu? essere nullo o zero. +field.not.null={0} non pu? essere nullo. +field.not.empty=la {0} non pu? essere vuota. +update_call_status_success_msg=Lo stato della chiamata ? stato aggiornato con successo. +status.same.error=Lo stato ? gi? impostato. +invalid.status.change.from.draft=Lo stato non pu? essere cambiato in READY_TO_PUBLISH o PUBLISH da DRAFT. +status.cannot.be.changed=Lo stato non pu? essere cambiato. +published.call.not.update=Il bando pubblicato non pu? essere aggiornato. +invalid.status.change.from.publish=Lo stato non pu? essere modificato in READY_TO_PUBLISH o DRAFT da PUBLISH. # Login-related messages login.successfully=Accesso effettuato con successo. pass.min.len.msg=La password deve essere lunga almeno 8 caratteri. -email.already.exists=Esiste gi� un utente con questa email. +email.already.exists=Esiste gi? un utente con questa email. invalid_user=Validazione utente fallita. Controlla le informazioni, lo stato dell'account e la scadenza del token. #Global messages -common_message=qualcosa é andato storto. Per favore riprova +common_message=qualcosa é andato storto. Per favore riprova invalid_signature=Gettone non valido. invalid_login=Nome utente o password errati req_validation_er=Errore di convalida @@ -119,26 +119,26 @@ lookupdata.created.successfully=LookUpData creato correttamente. lookupdata.fetched.successfully=LookUpData recuperato correttamente. lookupdata.updated.successfully=LookUpData aggiornato correttamente. lookupdata.deleted.successfully=LookUpData eliminato correttamente. -lookupdata.value.cannot.be.empty=Il campo valore non pu� essere vuoto +lookupdata.value.cannot.be.empty=Il campo valore non pu? essere vuoto #Document-related message document.updated.successfully=Documento aggiornato con successo. document.fetched.successfully=Documento recuperato con successo. # Password reset messages password.reset.initiated=Reimpostazione della password avviata. -password.reset.success=La password � stata reimpostata con successo. -invalid.token.msg=Il token fornito � invalido o scaduto. Si prega di richiedere un nuovo token. -current.password.incorrect = La password attuale non � corretta. +password.reset.success=La password ? stata reimpostata con successo. +invalid.token.msg=Il token fornito ? invalido o scaduto. Si prega di richiedere un nuovo token. +current.password.incorrect = La password attuale non ? corretta. success.password.changed=Password cambiata con successo. logout.successful.msg=Logout riuscito. Sei stato disconnesso con successo. -update.user.status.success=Lo stato dell'utente � stato aggiornato con successo. +update.user.status.success=Lo stato dell'utente ? stato aggiornato con successo. #Flow-related message flow.created.successfully=Flusso creato con successo. flow.fetched.successfully=Flusso recuperato con successo. -flow.already.exists= Il flusso esiste gi� per questa chiamata. -flow.request.not.complete=La richiesta di flusso non � completa. +flow.already.exists= Il flusso esiste gi? per questa chiamata. +flow.request.not.complete=La richiesta di flusso non ? completa. initial.and.final.form.cannot.null=La forma iniziale e finale non possono essere nulle. # Application related messages @@ -149,25 +149,25 @@ application.get.success=Dettagli dell'applicazione recuperati con successo. application.not.found=Applicazione non trovata con l'ID fornito. application.form.field.not.found=Campo del modulo di domanda non trovato. Form.not.matches.to.call.initial.form=L'ID del modulo non corrisponde all'ID del modulo iniziale della chiamata. -application.already.exists=L'applicazione esiste gi� per questa chiamata. -application.already.submitted=La domanda � gi� stata inviata. +application.already.exists=L'applicazione esiste gi? per questa chiamata. +application.already.submitted=La domanda ? gi? stata inviata. #Validation related messages -validation.field.required=Il campo {0} � obbligatorio. +validation.field.required=Il campo {0} ? obbligatorio. validation.field.min_length=Il campo {0} deve essere lungo almeno {1} caratteri. validation.field.max_length=Il campo {0} deve essere lungo al massimo {1} caratteri. validation.field.pattern=Il campo {0} non corrisponde al modello richiesto. validation.field.not_null=Il campo {0} non deve essere nullo. validation.field.not_empty=Il campo {0} non deve essere vuoto. -current.form.incomplete=il modulo corrente non � compilato +current.form.incomplete=il modulo corrente non ? compilato flow.not.found=Flow not found. validation.message=Messaggi di convalida. action.required=Campo azione obbligatorio. -call.not.published=La chiamata non � stata pubblicata. +call.not.published=La chiamata non ? stata pubblicata. application.form.not.found=Modulo di domanda non trovato. -application.is.incomplete = L'applicazione � incompleta. -updating.form.value.impact.on.flow=L'aggiornamento di questo valore del modulo {0} pu� avere un impatto sul flusso. +application.is.incomplete = L'applicazione ? incompleta. +updating.form.value.impact.on.flow=L'aggiornamento di questo valore del modulo {0} pu? avere un impatto sul flusso. validation.field.custom=Il valore per il campo {0} non soddisfa la regola di convalida personalizzata. validation.codice.fiscale=Il campo {0} deve essere un Codice Fiscale valido con esattamente 16 caratteri: 6 lettere, 2 cifre, 1 lettera, 2 cifre, 1 lettera, 3 cifre e 1 lettera. @@ -178,13 +178,13 @@ validation.email.pec=Il campo {0} deve essere un indirizzo email PEC valido. validation.url=Il campo {0} deve essere un URL valido. validation.marca.da.bollo=Il campo {0} deve essere una Marca Da Bollo valida con esattamente 14 cifre. validation.piva=Il numero di partita IVA per {0} deve essere lungo fino a 11 cifre. -valid.vat.number=Il numero di partita IVA non � valido per il campo {0}. +valid.vat.number=Il numero di partita IVA non ? valido per il campo {0}. failed.retain.field=Impossibile conservare campi specifici. token.validate.success=Token convalidato con successo. invalid.request=Richiesta non valida. -codice.fiscale.exists=Questo codice fiscale � gi� associato ad un altro utente. +codice.fiscale.exists=Questo codice fiscale ? gi? associato ad un altro utente. -total.steps.not.zero=Il totale dei passaggi non pu� essere zero. +total.steps.not.zero=Il totale dei passaggi non pu? essere zero. completed.steps.not.valid=I passaggi completati devono essere compresi tra 0 e il totale dei passaggi. field.id.not.found=L'ID campo {0} non esiste nella struttura del modulo. company.created.success=Azienda creata con successo. @@ -194,37 +194,37 @@ company.get.success=Azienda recuperata con successo. company.not.found=Azienda non trovata. check.vatnumber.success=Numero di partita IVA verificato con successo. 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�. +vatnumber.mandatory=Il numero di partita IVA ? obbligatorio. +vatnumber.already.exists=Il numero di partita IVA esiste gi?. invalid.email=Email non valida. -validation.error.missing.firstName=Il nome � obbligatorio. -validation.error.missing.lastName=Il cognome � obbligatorio. -validation.error.missing.codiceFiscale=Il Codice Fiscale � obbligatorio. +validation.error.missing.firstName=Il nome ? obbligatorio. +validation.error.missing.lastName=Il cognome ? obbligatorio. +validation.error.missing.codiceFiscale=Il Codice Fiscale ? obbligatorio. delegation.file.upload.success=File di delega caricato con successo. delegation.fetch.success=Delega recuperata con successo. -delegation.template.generation.error=Si � verificato un errore durante la generazione del modello di delega. -validation.error.file.empty=Il file caricato � vuoto. +delegation.template.generation.error=Si ? verificato un errore durante la generazione del modello di delega. +validation.error.file.empty=Il file caricato ? vuoto. validation.error.file.invalidType=Sono accettati solo file .p7m. upload.error.s3=Impossibile caricare il file su S3. -company.id.mandatory=L'ID dell'azienda � obbligatorio. -user.already.connected.to.company=L'utente � gi� collegato a questa azienda. -call.not.started.yet = La chiamata non � ancora iniziata. Attendere fino alla data e all'ora di inizio specificate. -call.already.ended = La chiamata � gi� terminata. Non � possibile inviare l'applicazione dopo la scadenza. +company.id.mandatory=L'ID dell'azienda ? obbligatorio. +user.already.connected.to.company=L'utente ? gi? collegato a questa azienda. +call.not.started.yet = La chiamata non ? ancora iniziata. Attendere fino alla data e all'ora di inizio specificate. +call.already.ended = La chiamata ? gi? terminata. Non ? possibile inviare l'applicazione dopo la scadenza. status.updated.successfully=Stato aggiornato con successo. application.status.updated.successfully = Stato dell'applicazione aggiornato con successo. -application.already.in.provided.status=L'applicazione � gi� nello stato fornito. +application.already.in.provided.status=L'applicazione ? gi? nello stato fornito. delegation.not.found=Delega non trovata. user.company.relation.not.found=Relazione utente con l'azienda specificata non trovata. delegation.delete.success=Delega eliminata con successo. user.not.authorized.create.application=L'utente deve essere un rappresentante legale o avere una delega. -application.submitted.cannot.change=La domanda inviata non pu� essere modificata. +application.submitted.cannot.change=La domanda inviata non pu? essere modificata. # Call Document Messages call.documents.fetch.success=Documenti recuperati con successo. call.documents.not.found=Nessun documento trovato per la chiamata specificata. # Beneficiary Preferred Call messages -beneficiary.preferred.call.status.updated.success=Lo stato della chiamata preferita del beneficiario � stato aggiornato con successo. +beneficiary.preferred.call.status.updated.success=Lo stato della chiamata preferita del beneficiario ? stato aggiornato con successo. beneficiary.preferred.calls.get.all.success=Tutte le chiamate preferite del beneficiario sono state recuperate con successo. beneficiary.preferred.call.created.success=Chiamata preferita del beneficiario creata con successo. beneficiary.preferred.call.get.success=Chiamata preferita del beneficiario recuperata con successo. @@ -233,7 +233,7 @@ beneficiary.preferred.calls.get.success=Tutte le chiamate preferite del benefici beneficiary.preferred.call.updated.success=Chiamata preferita del beneficiario aggiornata con successo. beneficiary.preferred.call.not.found=Chiamata preferita del beneficiario non trovata. either.user.or.beneficiary.id.required = ID utente o ID beneficiario non presente. -userId.and.beneficiaryId.error = Non � possibile fornire contemporaneamente sia userId che beneficiaryId. +userId.and.beneficiaryId.error = Non ? possibile fornire contemporaneamente sia userId che beneficiaryId. User.not.found.with.the.given.beneficiaryID=Utente non trovato con l'ID beneficiario fornito. permission.denied=Non sei autorizzato ad accedere a questi dati. signed.document.file.upload.success=File del documento firmato caricato con successo. @@ -244,10 +244,10 @@ delete.signed.document.file.success=Documento firmato eliminato con successo. dashboard.widget.fetched.successfully=Widget dashboard recuperato correttamente. login_attempt_successfully_created= Tentativo di login creato con successo. get_login_attempt_se_msg=Lista dei tentativi di accesso recuperata correttamente. -application.in.submit.status.cannot.delete.company=Non � possibile eliminare l'azienda perch� ci sono domande attive con stato SUBMITTED. +application.in.submit.status.cannot.delete.company=Non ? possibile eliminare l'azienda perch? ci sono domande attive con stato SUBMITTED. get.users.success.msg = Utenti recuperati con successo -cannot.create.beneficiary.user = La creazione di un utente beneficiario non � consentita. Si prega di assegnare il ruolo appropriato. +cannot.create.beneficiary.user = La creazione di un utente beneficiario non ? consentita. Si prega di assegnare il ruolo appropriato. evaluationCriteria.invalid=Questo criterio di valutazione non appartiene alla chiamata corrente. application.evaluation.not.found=Valutazione dell'applicazione non trovata con ID: {0} @@ -258,11 +258,11 @@ evaluation.deleted.successfully = Valutazione dell'applicazione eliminata con su evaluations.fetched.successfully = Tutte le valutazioni delle applicazioni recuperate con successo. application.evaluation.status.updated.successfully=Stato della valutazione dell'applicazione aggiornato con successo. assigned.application.not.found.with.id=Applicazione assegnata con questo ID dell'applicazione non trovata -either.application.or.assigned.application.id.required=� richiesto almeno uno tra applicationId o assignedApplicationId. -evaluation.already.exists=Una valutazione dell'applicazione esiste gi� per questo ID applicazione. +either.application.or.assigned.application.id.required=? richiesto almeno uno tra applicationId o assignedApplicationId. +evaluation.already.exists=Una valutazione dell'applicazione esiste gi? per questo ID applicazione. application.assigned.success.msg =Domanda assegnata con successo -application.already.assigned.msg =La domanda � gi� assegnata +application.already.assigned.msg =La domanda ? gi? assegnata aasigned.application.not.found = Applicazione assegnata non trovata con l'ID specificato. assigned.application.deleted.success =Applicazione assegnata eliminata con successo. assigned.application.get.success =Dettagli dell'applicazione assegnata recuperati correttamente. @@ -277,7 +277,7 @@ hub_get_all_success=Hub recuperati con successo hub_delete_success=Hub eliminato con successo hub_not_found=Hub non trovato -application.not.in.draft.status=La domanda non � in stato DRAFT. +application.not.in.draft.status=La domanda non ? in stato DRAFT. get.error.s3=Impossibile recuperare il file da S3. application.data.amendment.success = Recupero riuscito dei dati dell'applicazione per il processo di modifica @@ -292,19 +292,19 @@ added.comment.to.amendment.request.success = Commento aggiunto con successo alla comment.not.found = Commento non trovato. comment.updated.successfully = Commento aggiornato con successo. comment.deleted.successfully = Commento eliminato con successo. -comment.not.associate.with.amendment = Il commento non � associato alla richiesta di emendamento. +comment.not.associate.with.amendment = Il commento non ? associato alla richiesta di emendamento. amendment.found.success = Richiesta di emendamento trovata con successo. invalid.amendment.for.comment = Richiesta di emendamento non valida per il commento fornito. DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm create.application.data.amendment.msg =Emendamento alla domanda inviato con successo -beneficiary.email.not.found.msg=L'indirizzo email per il beneficiario non � stato trovato. Si prega di assicurarsi che il beneficiario abbia un indirizzo email valido. +beneficiary.email.not.found.msg=L'indirizzo email per il beneficiario non ? stato trovato. Si prega di assicurarsi che il beneficiario abbia un indirizzo email valido. reminder.email.sent.success.msg=Email di promemoria inviata con successo! application.documents.not.found=Nessun documento trovato per la domanda. -beneficiary.call.duplicate = Una chiamata preferita con questo ID di chiamata e ID azienda esiste gi� per questo utente. +beneficiary.call.duplicate = Una chiamata preferita con questo ID di chiamata e ID azienda esiste gi? per questo utente. 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. +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 @@ -324,7 +324,8 @@ appointment.creation.is.only.for.gepafin = La creazione degli appuntamenti ? con upload.document.is.only.for.gepafin = Il documento non pu? essere caricato, questa operazione ? disponibile solo per il Hub GEPAFIN. 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. +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. #notification messsages notification.already.in.state=La notifica è già nello stato fornito.