package net.gepafin.tendermanagement.dao; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.entities.SystemEmailTemplatesEntity.SystemEmailTemplatesEntityTypeEnum; import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.model.util.SortBy; import net.gepafin.tendermanagement.repositories.*; 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.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import static java.time.temporal.ChronoUnit.DAYS; import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; import static org.apache.commons.lang3.StringUtils.isEmpty; @Component public class ApplicationAmendmentRequestDao { @Value("${application.amendment.expiration.days}") private long expirationDays; @Autowired private ApplicationService applicationService; @Autowired private UserService userService; @Autowired private DocumentService documentService; @Autowired private ApplicationFormRepository applicationFormRepository; @Autowired private ApplicationAmendmentRequestRepository applicationAmendmentRequestRepository; @Autowired private ApplicationFormFieldRepository applicationFormFieldRepository; @Autowired private EmailNotificationDao emailNotificationDao; @Autowired private ApplicationEvaluationService applicationEvaluationService; @Autowired private ProtocolDao protocolDao; @Autowired private AssignedApplicationsService assignedApplicationsService; @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; @Autowired private ApplicationRepository applicationRepository; @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; @Autowired private SystemEmailTemplatesService systemEmailTemplatesService; @Autowired private HubService hubService; @Autowired private Validator validator; @Autowired private EmailLogDao emailLogDao; @Autowired private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; @Autowired LoggingUtil loggingUtil; @Autowired private HttpServletRequest request; @Autowired private AssignedApplicationsDao assignedApplicationsDao; @Autowired private ApplicationEvaluationDao applicationEvaluationDao; @Autowired private DocumentRepository documentRepository; @Autowired private CompanyService companyService; @Autowired private NotificationDao notificationDao; @Autowired private UserRepository userRepository; @Autowired private EvaluationFormRepository evaluationFormRepository; @Autowired private ApplicationEvaluationFormFieldRepository applicationEvaluationFormFieldRepository; @Autowired private ApplicationEvaluationFormRepository applicationEvaluationFormRepository; @Autowired private ApplicationAmendmentRequestViewRepository applicationAmendmentRequestViewRepository; @Autowired private ApplicationDao applicationDao; @Autowired private EmailLogRepository emailLogRepository; @Autowired private EmailDao emailDao; public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); Long applicationId = applicationEvaluationEntity.getApplicationId(); 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); } if(applicationEvaluationEntity.getEvaluationVersion().equals(EvaluationVersionEnum.V1.getValue())) { checklistValidationForEvaluationV1(evaluationFileRequests, checkList, checklistRequests); } else if (applicationEvaluationEntity.getEvaluationVersion().equals(EvaluationVersionEnum.V2.getValue())) { validationCheckEvaluationV2(applicationEvaluationEntity, application); } // Set common application-level details String callName = application.getCall().getName(); Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : null; UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : ""; String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : ""; String beneficiaryName = (!firstName.isBlank() ? firstName : "") + (!lastName.isBlank() ? " " + lastName : ""); beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName; ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse(); response.setId(applicationEvaluationId); response.setProtocolNumber(protocolNumber); response.setCallName(callName); response.setBeneficiaryName(beneficiaryName); response.setApplicationId(applicationId); response.setApplicationEvaluationId(applicationEvaluationId); 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"); result.addAll(filterByName(content, GepafinConstant.FILE_SELECT)); 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); return response; } private void validationCheckEvaluationV2(ApplicationEvaluationEntity applicationEvaluationEntity, ApplicationEntity application) { Long callId= applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication().getCall().getId(); EvaluationFormEntity evaluationFormEntity=evaluationFormRepository.findByCallIdAndIsDeletedFalse(callId); Long numberOfCheck= application.getCall().getNumberOfCheck(); ApplicationEvaluationFormEntity applicationEvaluationForm=applicationEvaluationFormRepository.findByApplicationEvaluation_IdAndIsDeletedFalse(applicationEvaluationEntity.getId()); List contentResponseBeans=Utils.convertJsonStringToList(evaluationFormEntity.getContent(),ContentResponseBean.class); int count = 0; for (ContentResponseBean content : contentResponseBeans) { if (GepafinConstant.SWITCH.equals(content.getName()) && content.getSettings().stream() .anyMatch(setting -> GepafinConstant.IS_CHECK_LIST_ITEM.equals(setting.getName()))) { ApplicationEvaluationFormFieldEntity field = applicationEvaluationFormFieldRepository .findByFieldIdAndApplicationEvaluationFormId(content.getId(), applicationEvaluationForm.getId()); if (field != null && Utils.isValidBoolean(field.getFieldValue())) { Boolean fieldValueAsBoolean = Boolean.parseBoolean(field.getFieldValue()); if (Boolean.FALSE.equals(fieldValueAsBoolean)) { throw new CustomValidationException(Status.VALIDATION_ERROR,GepafinConstant.VALIDATION_FAILED_FOR_CHECKLIST); } if (++count >= numberOfCheck) break; } } } } private static void checklistValidationForEvaluationV1(List evaluationFileRequests, String checkList, List checklistRequests) { 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)); } } public List getIdAndLabelFromResult(List> result) { List formFieldResponses = new ArrayList<>(); for (Map item : result) { AmendmentFormFieldResponse formFieldResponse = new AmendmentFormFieldResponse(); formFieldResponse.setFieldId((String) item.get("id")); // Extract "label" value from the "settings" array List> settings = (List>) item.get("settings"); String label = settings.stream() .filter(setting -> "label".equals(setting.get("name"))) .map(setting -> (String) setting.get("value")) .findFirst() .orElse(""); // Default to empty string if not found if (label == null || label.trim().isEmpty()) { continue; } formFieldResponse.setLabel(label); // Set the label as fieldValue formFieldResponses.add(formFieldResponse); } return formFieldResponses; } public static List> filterByName(String content, String target) { ObjectMapper objectMapper = new ObjectMapper(); List> filteredList = new ArrayList<>(); try { List> dataList = objectMapper.readValue( content, new TypeReference>>() { }); for (Map data : dataList) { if (target.equals(data.get("name"))) { filteredList.add(data); } } } catch (Exception e) { e.printStackTrace(); } return filteredList; } public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(Long applicationEvaluationId, ApplicationAmendmentRequest applicationAmendmentRequest) { log.info("Submiting application data for amendment Process with details: {}", applicationEvaluationId); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = createApplicationAmendmentRequestEntity(applicationAmendmentRequest, applicationEvaluationId); ApplicationAmendmentRequestResponse applicationAmendmentRequestResponse = convertEntityToResponse(applicationAmendmentRequestEntity,false); log.info("Application submitted successfully for amendment", applicationAmendmentRequestResponse); if (Boolean.TRUE.equals(applicationAmendmentRequestResponse.getIsSendEmail())) { emailNotificationDao.sendMailToNotifyBeneficiaryRegardingNewAmendment(applicationAmendmentRequestEntity); EmailSendResponse emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); List responses = List.of(emailSendResponse); if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())){ saveEmailSendResponse(emailSendResponse, applicationAmendmentRequestEntity); applicationAmendmentRequestResponse.setEmailSendResponse(responses); } else{ applicationAmendmentRequestResponse.setEmailSendResponse(Collections.emptyList()); } } return applicationAmendmentRequestResponse; } public ApplicationAmendmentRequestEntity createApplicationAmendmentRequestEntity(ApplicationAmendmentRequest applicationAmendmentRequest,Long applicationEvaluationId) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); if(applicationAmendmentRequest.getResponseDays()==null || applicationAmendmentRequest.getResponseDays() < 0){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.RESPONSE_DAYS_NOT_NULL)); } applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequest.getResponseDays())); applicationAmendmentRequestEntity.setIsEmail(applicationAmendmentRequest.getIsSendEmail()); applicationAmendmentRequestEntity.setIsNotification(applicationAmendmentRequest.getIsSendNotification()); applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.AWAITING.getValue()); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); //cloned for old data entity ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); applicationAmendmentRequestEntity.setApplicationEvaluationEntity(applicationEvaluationEntity); Long applicationId = applicationEvaluationEntity.getApplicationId(); Long assignedApplicationId = applicationEvaluationEntity.getAssignedApplicationsEntity().getId(); applicationAmendmentRequestEntity.setApplicationId(applicationId); if (applicationAmendmentRequest.getFormFields() != null) { List formFieldRequestBean = applicationAmendmentRequest.getFormFields().stream() .filter(AmendmentFormFieldResponse::isSelected) .map(amendmentFormFieldRequest -> { AmendmentFormField formField = new AmendmentFormField(); formField.setFieldId(amendmentFormFieldRequest.getFieldId()); formField.setFieldValue(null); formField.setLabel(amendmentFormFieldRequest.getLabel()); return formField; }) .collect(Collectors.toList()); String formFieldsJson = Utils.convertObjectToJson(formFieldRequestBean); applicationAmendmentRequestEntity.setFormFields(formFieldsJson); } List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId()); // Ensure startDate and initialDays are not null to avoid NullPointerException if (amendmentRequest !=null && amendmentRequest.isEmpty() && applicationEvaluationEntity.getStartDate() != null && applicationEvaluationEntity.getInitialDays() != null ) { Long initialDays = applicationEvaluationEntity.getInitialDays(); LocalDateTime startDate = applicationEvaluationEntity.getStartDate(); LocalDateTime nowInUTC = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); // Calculate remaining days Long remainingDays = initialDays - DAYS.between(startDate, nowInUTC); // Set remaining days in the entity applicationEvaluationEntity.setRemainingDays(remainingDays); //Set stop date time in the entity becuase amendment has started applicationEvaluationEntity.setStopDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); } UserEntity userEntity = userService.validateUser(applicationEvaluationEntity.getUserId()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( applicationEvaluationEntity.getAssignedApplicationsEntity().getApplication(), protocolNumber, userEntity.getHub().getId(),false); applicationAmendmentRequestEntity.setProtocol(protocolEntity); ApplicationAmendmentRequestEntity applicationAmendment = saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity, null, VersionActionTypeEnum.INSERT); String evaluationStatusType = applicationEvaluationEntity.getStatus(); if (Boolean.FALSE.equals(evaluationStatusType.equals((ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue())))){ // applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); //Set Status applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); applicationEvaluationRepository.save(applicationEvaluationEntity); /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluationEntity).build()); } ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity); String applicationStatusType = applicationEntity.getStatus(); if (Boolean.FALSE.equals(applicationStatusType.equals((ApplicationStatusTypeEnum.SOCCORSO.getValue())))) { applicationEntity.setStatus(ApplicationStatusTypeEnum.SOCCORSO.getValue()); applicationRepository.save(applicationEntity); } /** This code is responsible for adding a version history log for the "Update Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntity).newData(applicationEntity).build()); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsService.validateAssignedApplication(assignedApplicationId); String assignedStatusType = assignedApplicationsEntity.getStatus(); AssignedApplicationsEntity oldAssignedApplication = Utils.getClonedEntityForData(assignedApplicationsEntity); if (Boolean.FALSE.equals(assignedStatusType.equals((AssignedApplicationEnum.SOCCORSO.getValue())))) { assignedApplicationsEntity.setStatus(AssignedApplicationEnum.SOCCORSO.getValue()); assignedApplicationsRepository.save(assignedApplicationsEntity); Map placeHolders = notificationDao.sendNotificationToBeneficiary(applicationEntity, NotificationTypeEnum.AMENDMENT_CREATION); notificationDao.sendNotificationToInstructor(placeHolders,applicationAmendmentRequestEntity.getApplicationEvaluationEntity(),NotificationTypeEnum.AMENDMENT_CREATION); /** This code is responsible for adding a version history log for the "Update Assigned Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplication).newData(assignedApplicationsEntity).build()); } 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); /** This code is responsible for adding a version history log for the "Create Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionTypeEnum).oldData(oldApplicationAmendmentEntity).newData(applicationAmendmentRequestEntity).build()); return applicationAmendmentRequest; } public ApplicationAmendmentRequestResponse convertEntityToResponse(ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity,boolean includeEmailContent) { ApplicationAmendmentRequestResponse response = initializeBasicResponse(applicationAmendmentRequestEntity,includeEmailContent); 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,boolean includeEmailContent) { ApplicationAmendmentRequestResponse response = new ApplicationAmendmentRequestResponse(); ApplicationEntity applicationEntity = entity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication(); Long hubId = applicationEntity.getHubId(); HubEntity hubEntity = hubService.valdateHub(hubId); response.setEmailSendResponse(entity.getEmailSendResponse()); response.setId(entity.getId()); response.setApplicationId(entity.getApplicationId()); response.setApplicationEvaluationId(entity.getApplicationEvaluationEntity().getId()); response.setNote(entity.getNote()); response.setStatus(ApplicationAmendmentRequestEnum.valueOf(entity.getStatus())); response.setResponseDays(entity.getResponseDays()); response.setInternalNote(entity.getInternalNote()); LocalDateTime startDate = entity.getStartDate(); response.setStartDate(startDate); response.setExpirationDate(entity.getEndDate()); response.setEvaluationEndDate(entity.getApplicationEvaluationEntity().getEndDate()); response.setIsSendEmail(entity.getIsEmail()); response.setIsSendNotification(entity.getIsNotification()); ApplicationEntity application = applicationService.validateApplication(entity.getApplicationId()); response.setCallEmail(application.getCall().getEmail()); response.setCallName(application.getCall().getName()); UserEntity userEntity = userService.validateUser(application.getUserId()); response.setBeneficiaryName(buildBeneficiaryName(userEntity)); CompanyEntity company = companyService.validateCompany(application.getCompanyId()); response.setCompanyName(company.getCompanyName()); Long protocolNumber = entity.getProtocol() != null ? entity.getProtocol().getProtocolNumber() : null; response.setProtocolNumber(protocolNumber); if (includeEmailContent) { Map bodyPlaceholders = emailNotificationDao.prepareEmailPlaceholders(applicationEntity, entity); EmailContentResponse emailContent = emailNotificationDao.prepareEmailContent(applicationEntity, SystemEmailTemplatesEntityTypeEnum.DOCUMENTATION_INTEGRATION_REQUEST, hubEntity, bodyPlaceholders); String body = emailContent.getBody(); response.setEmailTemplate(body); } return response; } private Map extractFieldIdToLabelMap(List forms) { return forms.stream() .flatMap(form -> { String content = form.getForm().getContent(); List> filteredResults = new ArrayList<>(); filteredResults.addAll(filterByName(content, "fileupload")); filteredResults.addAll(filterByName(content, GepafinConstant.FILE_SELECT)); return getIdAndLabelFromResult(filteredResults).stream(); }) .collect(Collectors.toMap(AmendmentFormFieldResponse::getFieldId, AmendmentFormFieldResponse::getLabel)); } private Map getApplicationFormFieldEntityMap( ApplicationAmendmentRequestEntity entity, List amendmentFormFields) { List fieldIds = amendmentFormFields.stream() .map(AmendmentFormField::getFieldId) .toList(); return getApplicationFormFieldList(entity, fieldIds).stream() .collect(Collectors.toMap(ApplicationFormFieldEntity::getFieldId, Function.identity())); } private void processFormFields(List amendmentFormFields, Map fieldIdToLabelMap, Map formFieldEntityMap, ApplicationAmendmentRequestResponse response) { List formFields = new ArrayList<>(); List fileDetails = new ArrayList<>(); for (AmendmentFormField amendmentFormField : amendmentFormFields) { // Create form field response createFormField(formFields, fieldIdToLabelMap, amendmentFormField); // Create document responses List documentIds = extractIds(amendmentFormField.getFieldValue()); List documentResponseBeans = documentIds.stream() .map(id -> { DocumentEntity documentEntity = documentService.validateDocument(id); DocumentResponseBean responseBean = new DocumentResponseBean(); responseBean.setId(documentEntity.getId()); responseBean.setName(documentEntity.getFileName()); responseBean.setType(DocumentTypeEnum.valueOf(documentEntity.getType())); responseBean.setSource(DocumentSourceTypeEnum.valueOf(documentEntity.getSource())); responseBean.setSourceId(documentEntity.getSourceId()); responseBean.setFilePath(documentEntity.getFilePath()); responseBean.setCreatedDate(documentEntity.getCreatedDate()); responseBean.setUpdatedDate(documentEntity.getUpdatedDate()); responseBean.setDocumentAttachmentId(documentEntity.getDocumentAttachmentId()); return responseBean; }) .toList(); // Map to application form field response bean ApplicationFormFieldEntity formFieldEntity = formFieldEntityMap.get(amendmentFormField.getFieldId()); ApplicationFormFieldResponseBean responseBean = new ApplicationFormFieldResponseBean(); responseBean.setApplicationFormId(formFieldEntity.getApplicationForm().getId()); responseBean.setId(formFieldEntity.getId()); responseBean.setFieldId(amendmentFormField.getFieldId()); responseBean.setCreatedDate(formFieldEntity.getCreatedDate()); responseBean.setUpdatedDate(formFieldEntity.getUpdatedDate()); responseBean.setFieldValue(documentResponseBeans); fileDetails.add(responseBean); } response.setFormFields(formFields); response.setApplicationFormFields(fileDetails); } private String buildBeneficiaryName(UserEntity userEntity) { if (userEntity.getBeneficiary() == null) { return ""; } String firstName = userEntity.getBeneficiary().getFirstName(); String lastName = userEntity.getBeneficiary().getLastName(); return (firstName != null ? firstName : "") + (lastName != null && !lastName.isBlank() ? " " + lastName : ""); } private void createFormField(List formFields, Map fieldIdToLabelMap, AmendmentFormField amendmentFormField) { AmendmentFormFieldResponse formField = new AmendmentFormFieldResponse(); String label = fieldIdToLabelMap.get(amendmentFormField.getFieldId()); formField.setFieldId(amendmentFormField.getFieldId()); formField.setLabel(label); formField.setSelected(true); formFields.add(formField); } public ApplicationAmendmentRequestEntity validateApplicationAmendmentRequest(Long id) { return applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); } public void deleteById(Long id) { log.info("Deleting assigned application with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); applicationAmendmentRequestEntity.setIsDeleted(true); saveApplicationAmendmentRequestEntity(applicationAmendmentRequestEntity,oldApplicationAmendmentEntity,VersionActionTypeEnum.SOFT_DELETE); log.info(" Application amendment deleted with ID: {}", id); } public ApplicationAmendmentRequestResponse getApplicationAmendmentRequestById(Long id) { log.info("Fetching application amendment with ID: {}", id); ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); ApplicationAmendmentRequestResponse response = convertEntityToResponse(applicationAmendmentRequestEntity,true); response.setEmailSendResponse(applicationAmendmentRequestEntity.getEmailSendResponse()); return response; } public List getAllApplicationAmendmentRequest(HttpServletRequest request, Long userId) { if (validator.checkIsPreInstructor() && userId == null) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.USER_ID_NOT_NULL_MSG)); } if (userId != null) { validator.validatePreInstructor(request, userId); } Specification spec = search(userId); List applicationAmendmentRequestEntities = applicationAmendmentRequestRepository.findAll(spec); return applicationAmendmentRequestEntities.stream() .map(this::initializeGetAllBasicResponse) .collect(Collectors.toList()); } private Specification search(Long userId) { return (root, query, builder) -> { Predicate predicate = builder.isFalse(root.get("isDeleted")); // Only non-deleted records if (userId != null) { Join evaluationJoin = root.join("applicationEvaluationEntity"); predicate = builder.and(predicate, builder.equal(evaluationJoin.get("userId"), userId)); } return predicate; // Return final predicate }; } public ApplicationAmendmentRequestResponse updateApplicationAmendment( Long id, ApplicationAmendmentRequestBean updateRequest) { log.info("Updating application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); Boolean isBeneficiary=false; if (Boolean.FALSE.equals(validator.checkIsBeneficiary()) && Boolean.FALSE.equals(validator.checkIsConfidi()) ) { 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()); Map amendmentFormFieldMap = Utils .convertJsonStringToList(existingApplicationAmendment.getFormFields(), AmendmentFormField.class) .stream().collect(Collectors.toMap(AmendmentFormField::getFieldId, Function.identity())); Map applicationFormFieldMap = getApplicationFormFieldList(existingApplicationAmendment, amendmentFormFieldMap.keySet().stream().toList()).stream().collect(Collectors.toMap(ApplicationFormFieldEntity::getFieldId, Function.identity())); 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); 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,false); log.info("Application Amendment updated successfully: {}", response); return response; } private List updateApplicationFormField(ApplicationFormFieldEntity applicationFormFieldEntity, ApplicationFormFieldRequestBean applicationFormFieldRequest, AmendmentFormField amendmentFormField) { // Step 1: Extract IDs List applicationFormFieldIds = extractIds(applicationFormFieldEntity.getFieldValue()); List amendmentFormFieldIds = extractIds(amendmentFormField.getFieldValue()); List requestedIds = extractIds(applicationFormFieldRequest.getFieldValue()); // Step 2: Optimize operations by finding differences // Remove only those IDs from currentIds that exist in presentIds but not in requestedIds List idsToRemove = amendmentFormFieldIds.stream() .filter(id -> !requestedIds.contains(id)) .toList(); applicationFormFieldIds.removeAll(idsToRemove); // Add only those IDs to currentIds that exist in requestedIds but not in presentIds List idsToAdd = requestedIds.stream() .filter(id -> !amendmentFormFieldIds.contains(id)) .toList(); applicationFormFieldIds.addAll(idsToAdd); // Step 3: Update the applicationFormFieldEntity fieldValue with requestedIds if it has changed if (!amendmentFormFieldIds.equals(requestedIds)) { String updatedFieldValue = applicationFormFieldIds.stream() .map(String::valueOf) .collect(Collectors.joining(",")); applicationFormFieldEntity.setFieldValue(updatedFieldValue); applicationFormFieldRepository.save(applicationFormFieldEntity); } // Step 4: Return the updated currentIds return applicationFormFieldIds; } private ApplicationFormFieldEntity getApplicationFormField( Map applicationFormFieldMap, String fieldId) { ApplicationFormFieldEntity applicationFormFieldEntity = applicationFormFieldMap.get(fieldId); if (applicationFormFieldEntity == null) { throw new CustomValidationException(Status.BAD_REQUEST, GepafinConstant.APPLICATION_FORM_FIELD_NOT_FOUND); } return applicationFormFieldEntity; } private List getApplicationFormFieldList( ApplicationAmendmentRequestEntity applicationAmendment, List fieldIds) { List applicationFormList = applicationFormRepository .findByApplicationId(applicationAmendment.getApplicationId()); return applicationFormList.stream().flatMap(applicationForm -> applicationFormFieldRepository .findByApplicationFormIdAndFieldIdIn(applicationForm.getId(), fieldIds).stream()).toList(); } private AmendmentFormField getAmendmentFormField(Map amendmentFormFieldMap, String fieldId) { AmendmentFormField amendmentFormField = amendmentFormFieldMap.get(fieldId); if (amendmentFormField == null) { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_FORM_FIELD_NOT_FOUND)); } return amendmentFormField; } private void updateFormField(AmendmentFormFieldRequest applicationFormFieldRequest, AmendmentFormField amendmentFormField) { List requestedDocumentIds = extractIds(applicationFormFieldRequest.getFieldValue()); List existingDocumentIds = extractIds(amendmentFormField.getFieldValue()); if (requestedDocumentIds.isEmpty()) { if (!existingDocumentIds.isEmpty()) { existingDocumentIds.forEach(this::softDeleteDocument); amendmentFormField.setFieldValue(null); amendmentFormField.setValid(applicationFormFieldRequest.getValid()); // setIsUploadedBy(amendmentFormField); } return; } requestedDocumentIds.forEach(documentId -> documentService.validateDocument(documentId).getId()); existingDocumentIds.stream().filter(documentId -> !requestedDocumentIds.contains(documentId)) .forEach(this::softDeleteDocument); String newFieldValue = String.join(",", requestedDocumentIds.stream().map(String::valueOf).collect(Collectors.toList())); if (!newFieldValue.equals(amendmentFormField.getFieldValue())) { amendmentFormField.setFieldValue(newFieldValue); amendmentFormField.setValid(applicationFormFieldRequest.getValid()); // setIsUploadedBy(amendmentFormField); } } public List extractIds(Object fieldValue) { if (fieldValue instanceof String && !StringUtils.isEmpty((String) fieldValue)) { return Arrays.stream(((String) fieldValue).split(",")) .map(Long::valueOf) .collect(Collectors.toList()); } return Collections.emptyList(); } // 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) { // if (updatedFormField.getFieldValue() == null || "".equals(updatedFormField.getFieldValue().toString().trim())) { // List applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId()); // // boolean fieldUpdated = false; // // for (ApplicationFormEntity applicationForm : applicationForms) { // Optional formFieldEntityOptional = applicationFormFieldRepository // .findByApplicationFormIdAndFieldId(applicationForm.getId(), updatedFormField.getFieldId()); // // if (formFieldEntityOptional.isPresent()) { // ApplicationFormFieldEntity formEntity = formFieldEntityOptional.get(); // formEntity.setFieldValue(null); // Set field value to null // applicationFormFieldRepository.save(formEntity); // log.info("Set field value to null for application ID {} and field ID {}", applicationAmendment.getApplicationId(), updatedFormField.getFieldId()); // fieldUpdated = true; // break; // } // } // // if (!fieldUpdated) { // throw new CustomValidationException(Status.NOT_FOUND, "No ApplicationFormField found for application ID " + applicationAmendment.getApplicationId() + " and field ID " + updatedFormField.getFieldId()); // } // return; // } // // List documentIds; // // if (updatedFormField.getFieldValue() instanceof String && updatedFormField.getFieldValue() != null) { // documentIds = Arrays.asList(((String) updatedFormField.getFieldValue()).split(",")); // } else { // log.warn("Expected fieldValue as a comma-separated String but got: {}", updatedFormField.getFieldValue()); // return; // } // // List validDocumentIds = new ArrayList<>(); // for (String documentId : documentIds) { // try { // DocumentEntity documentEntity = documentService.validateDocument(Long.parseLong(documentId.trim())); // if (documentEntity != null) { // validDocumentIds.add(documentId.trim()); // } else { // log.warn("Document with ID {} does not exist. Skipping this ID.", documentId); // } // } catch (NumberFormatException e) { // log.error("Invalid document ID format: {}. Error: {}", documentId, e.getMessage()); // } // } // // if (!validDocumentIds.isEmpty()) { // List applicationForms = applicationFormRepository.findByApplicationId(applicationAmendment.getApplicationId()); // // boolean fieldUpdated = false; // // // Parse the formFields JSON string to get amendment field values // String amendmentFieldValue = null; // try { // ObjectMapper mapper = new ObjectMapper(); // List amendmentFields = mapper.readValue( // applicationAmendment.getFormFields(), // mapper.getTypeFactory().constructCollectionType(List.class, ApplicationFormFieldRequestBean.class) // ); // // // Find the matching field value and convert to string if found // Optional amendmentFieldObj = amendmentFields.stream() // .filter(field -> updatedFormField.getFieldId().equals(field.getFieldId())) // .map(ApplicationFormFieldRequestBean::getFieldValue) // .findFirst(); // // if (amendmentFieldObj.isPresent() && amendmentFieldObj.get() instanceof String) { // amendmentFieldValue = (String) amendmentFieldObj.get(); // } // // } catch (JsonProcessingException e) { // log.error("Error parsing formFields JSON: {}", e.getMessage()); // return; // } // // if (amendmentFieldValue == null) { // log.warn("No matching field found in amendment for field ID {}", updatedFormField.getFieldId()); // return; // } // // List amendmentDocumentIds = Arrays.asList(amendmentFieldValue.split(",")); // // for (ApplicationFormEntity applicationForm : applicationForms) { // Optional formFieldEntityOptional = applicationFormFieldRepository // .findByApplicationFormIdAndFieldId(applicationForm.getId(), updatedFormField.getFieldId()); // // if (formFieldEntityOptional.isPresent()) { // ApplicationFormFieldEntity formEntity = formFieldEntityOptional.get(); // // // Retrieve existing document IDs in ApplicationFormFieldTable // String existingFieldValue = formEntity.getFieldValue(); // Set existingDocumentIds = existingFieldValue != null // ? new HashSet<>(Arrays.asList(existingFieldValue.split(","))) // : new HashSet<>(); // // // Remove amendment documents from existing document IDs // existingDocumentIds.removeAll(amendmentDocumentIds); // // // Add valid new document IDs from the request // existingDocumentIds.addAll(validDocumentIds); // applicationDao.updateDocumentDeletionStatus(formEntity, updatedFormField, formEntity.getApplicationForm().getForm(), null,validDocumentIds,true); // // Set the combined document IDs back as the field value // formEntity.setFieldValue(String.join(",", existingDocumentIds)); // applicationFormFieldRepository.save(formEntity); // log.info("Updated field value for application ID {} and field ID {} with document IDs {}", // applicationAmendment.getApplicationId(), updatedFormField.getFieldId(), String.join(",", existingDocumentIds)); // fieldUpdated = true; // break; // } // } // // if (!fieldUpdated) { // throw new CustomValidationException(Status.NOT_FOUND, // String.format("No ApplicationFormField found for application ID %s and field ID %s. Skipping update.", // applicationAmendment.getApplicationId(), updatedFormField.getFieldId())); // } // } else { // log.warn("No valid document IDs found for update. Skipping field ID {}", updatedFormField.getFieldId()); // } // } // // // private void updateFormFieldsJson(ApplicationAmendmentRequestEntity applicationAmendment, ApplicationFormFieldRequestBean updatedFormField) { // if (updatedFormField != null) { // try { // // Step 1: Fetch the existing form fields JSON // String existingFormFieldsJson = applicationAmendment.getFormFields(); // List formFieldsList; // // if (existingFormFieldsJson == null || existingFormFieldsJson.isEmpty()) { // formFieldsList = new ArrayList<>(); // If no existing data, start with an empty list // } else { // // Step 2: Deserialize the existing JSON into a list of objects // formFieldsList = new ObjectMapper().readValue(existingFormFieldsJson, new TypeReference>() { // }); // } // // // Step 3: Check if the field ID already exists in the list and update it // boolean fieldUpdated = false; // for (ApplicationFormFieldRequestBean field : formFieldsList) { // if (field.getFieldId().equals(updatedFormField.getFieldId())) { // field.setFieldValue(updatedFormField.getFieldValue()); // Update field value // fieldUpdated = true; // break; // } // } // // // If field wasn't updated, log a warning message instead of adding a new field // if (!fieldUpdated) { // log.warn("Field ID {} does not exist in the form fields for application amendment ID {}", updatedFormField.getFieldId(), applicationAmendment.getId()); // throw new CustomValidationException(Status.NOT_FOUND, "Field ID {} does not exist in the form fields for application amendment ID {}"); // // } // // // Step 4: Serialize the updated list back to JSON if the update was successful // String updatedFormFieldsJson = new ObjectMapper().writeValueAsString(formFieldsList); // applicationAmendment.setFormFields(updatedFormFieldsJson); // Update the form fields with the modified list // // log.info("Updated form fields JSON for application amendment ID {}: {}", applicationAmendment.getId(), updatedFormFieldsJson); // // } catch (JsonProcessingException e) { // log.error("Error processing JSON for form fields for application amendment ID {}: {}", applicationAmendment.getId(), e.getMessage()); // throw new CustomValidationException(Status.BAD_REQUEST, "Error processing JSON for form fields"); // } // } else { // log.warn("No form field data to update for application amendment ID {}", applicationAmendment.getId()); // throw new CustomValidationException(Status.NOT_FOUND, "No form field data to update for application amendment ID {}"); // } // } public List getAllAmendmentRequestByBeneficiaryId(Long beneficiaryUserId) { UserEntity userEntity = userService.validateUser(beneficiaryUserId); List entities = applicationAmendmentRequestRepository.findByUserId(beneficiaryUserId); return entities.stream() .map(entity -> convertEntityToResponse(entity, false)) .collect(Collectors.toList()); } public ApplicationAmendmentRequestResponse closeAmendmentRequest(Long id, CloseAmendmentRequest closeAmendmentRequest) { log.info("Closing application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); //cloned entity for old data and versioning ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(existingApplicationAmendment); List amendmentRequestList = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( existingApplicationAmendment.getApplicationEvaluationEntity().getId() ); // Check if this is the last amendment being closed boolean isLastRemaining = amendmentRequestList.stream() .filter(amendment -> !amendment.getId().equals(id)) // Exclude the current amendment .allMatch(amendment -> amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue())); if (isLastRemaining) { log.info("The current amendment is the last remaining one to be closed."); applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(existingApplicationAmendment.getApplicationEvaluationEntity()); } setIfUpdated(existingApplicationAmendment::getInternalNote, existingApplicationAmendment::setInternalNote, closeAmendmentRequest.getInternalNote()); setIfUpdated(existingApplicationAmendment::getStatus, existingApplicationAmendment::setStatus, ApplicationAmendmentRequestEnum.CLOSE.getValue()); existingApplicationAmendment.setClosingDate(LocalDateTime.now()); ApplicationAmendmentRequestEntity updatedApplicationAmendment = saveApplicationAmendmentRequestEntity(existingApplicationAmendment, oldApplicationAmendmentEntity, VersionActionTypeEnum.UPDATE); ApplicationAmendmentRequestResponse response = convertEntityToResponse(updatedApplicationAmendment,false); List amendmentRequests = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( existingApplicationAmendment.getApplicationEvaluationEntity().getId()); Boolean allClosed = amendmentRequests.stream().allMatch(amendment -> (amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue()) || amendment.getStatus().equals(ApplicationAmendmentRequestEnum.EXPIRED.getValue()))); ApplicationEntity application = applicationService.validateApplication(existingApplicationAmendment.getApplicationId()); ApplicationEntity oldApplicationEntityData = Utils.getClonedEntityForData(application); if (Boolean.TRUE.equals(allClosed)) { existingApplicationAmendment.getApplicationEvaluationEntity().setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); if (allClosed) { ApplicationEvaluationEntity existingApplicationEvaluationEntity = existingApplicationAmendment.getApplicationEvaluationEntity(); ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(existingApplicationEvaluationEntity); existingApplicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); applicationEvaluationRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity()); application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); applicationRepository.save(application); AssignedApplicationsEntity assignedApplicationsEntity = assignedApplicationsDao.validateAssignedApplication( existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getId()); AssignedApplicationsEntity oldAssignedApplicationData = Utils.getClonedEntityForData(assignedApplicationsEntity); existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity().setStatus(AssignedApplicationEnum.OPEN.getValue()); assignedApplicationsEntity = assignedApplicationsRepository.save(existingApplicationAmendment.getApplicationEvaluationEntity().getAssignedApplicationsEntity()); Map placeHolders = notificationDao.sendNotificationToBeneficiary(application, NotificationTypeEnum.AMENDMENT_CLOSED); notificationDao.sendNotificationToInstructor(placeHolders,existingApplicationAmendment.getApplicationEvaluationEntity(),NotificationTypeEnum.AMENDMENT_CLOSED); /** This code is responsible for adding a version history log for the "Update Application Evaluation" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity) .newData(existingApplicationEvaluationEntity).build()); /** This code is responsible for adding a version history log for the "Update Application status" operation. **/ loggingUtil.addVersionHistory( VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEntityData).newData(application).build()); /** This code is responsible for adding a version history log for the "Update assigned application " operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationData) .newData(assignedApplicationsEntity).build()); log.info("All amendments are closed. Application Evaluation status set to OPEN."); } log.info("Application Amendment closed successfully: {}", response); } return response; } public ApplicationAmendmentRequestResponse extendResponseDays(Long id, Long newResponseDays) { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); if (newResponseDays != null && newResponseDays > 0) { ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); Long currentResponseDays = applicationAmendmentRequestEntity.getResponseDays() != null ? applicationAmendmentRequestEntity.getResponseDays() : 0L; applicationAmendmentRequestEntity.setResponseDays(currentResponseDays + newResponseDays); applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(applicationAmendmentRequestEntity.getResponseDays()))); applicationAmendmentRequestRepository.save(applicationAmendmentRequestEntity); /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationAmendmentEntity).newData(applicationAmendmentRequestEntity).build()); } return convertEntityToResponse(applicationAmendmentRequestEntity,false); } public List getAmendmentByApplicationId(HttpServletRequest request, Long applicationId, List statuses) { log.info("Fetching the Amendment data from application id {}", applicationId); ApplicationEntity application = applicationService.validateApplication(applicationId); List applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByApplicationIdAndIsDeletedFalse(applicationId); if (statuses != null && !statuses.isEmpty()) { List statusStrings = statuses.stream().map(Enum::name).collect(Collectors.toList()); applicationAmendmentRequestEntity = applicationAmendmentRequestRepository.findByApplicationIdAndStatusInAndIsDeletedFalse(application.getId(), statusStrings); } if (!applicationAmendmentRequestEntity.isEmpty()) { ApplicationAmendmentRequestEntity applicationAmendmentRequest = applicationAmendmentRequestEntity.get(0); Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationAmendmentRequest.getApplicationEvaluationEntity().getId()); if (entityOptional.isPresent()) { if (Boolean.FALSE.equals(validator.checkIsBeneficiary())) { validator.validatePreInstructor(request, entityOptional.get().getUserId()); } else { validator.validateUserId(request, entityOptional.get().getAssignedApplicationsEntity().getApplication().getUserId()); } } } List response = new ArrayList<>(); if (applicationAmendmentRequestEntity != null) { response = applicationAmendmentRequestEntity.stream() .map(entity -> convertEntityToResponse(entity, true)) .collect(Collectors.toList()); } return response; } public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus( Long id, ApplicationAmendmentRequestEnum statusTypeEnum) { 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))) { existingApplicationAmendment.setStatus(ApplicationAmendmentRequestEnum.RESPONSE_RECEIVED.getValue()); existingApplicationAmendment.setUpdatedDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); applicationAmendmentRequestRepository.save(existingApplicationAmendment); /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationAmendmentEntity).newData(existingApplicationAmendment).build()); } ApplicationAmendmentRequestResponse response = convertEntityToResponse(existingApplicationAmendment,false); log.info("Amendment status updated successfully: {}", response); return response; } public EmailReminderResponse sendReminderEmail(Long amendmentId) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(amendmentId) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, Translator.toLocale(GepafinConstant.APPLICATION_AMENDMENT_NOT_FOUND_MSG))); Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(amendment.getApplicationEvaluationEntity().getId()); EmailReminderResponse emailReminderResponse = new EmailReminderResponse(); if (entityOptional.isPresent()) { ApplicationEntity applicationEntity = applicationService.validateApplication(entityOptional.get().getApplicationId()); UserEntity beneficiaryUser = userService.validateUser(applicationEntity.getUserId()); HubEntity hub = hubService.valdateHub(applicationEntity.getHubId()); SystemEmailTemplateResponse emailTemplate = systemEmailTemplatesService.retrieveTemplateByTypeAndCall(SystemEmailTemplatesEntityTypeEnum.AMENDMENT_REMINDER, hub, null); String subject = prepareSubject(emailTemplate, amendment, beneficiaryUser); String body = prepareBody(emailTemplate, amendment, beneficiaryUser); String email = beneficiaryUser.getEmail(); if (Boolean.TRUE.equals(amendment.getIsEmail()) && email != null && !email.isEmpty()) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(emailTemplate.getEmailScenario(), RecipientTypeEnum.USER, beneficiaryUser.getId(), email, beneficiaryUser.getId(), applicationEntity.getId(), amendment.getId(), applicationEntity.getCall().getId()); emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(email), emailLogRequest); EmailSendResponse emailSendResponse = emailDao.buildEmailSendResponseFromRequest(request); List responses = List.of(emailSendResponse); if (!Boolean.TRUE.equals(emailSendResponse.getIsEmailSend())){ emailReminderResponse.setEmailSendResponse(responses); saveEmailSendResponse(emailSendResponse, amendment); } else{ emailReminderResponse.setEmailSendResponse(Collections.emptyList()); } } else { throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.BENEFICIARY_EMAIL_NOT_FOUND_MSG)); } } return emailReminderResponse; } private String prepareSubject(SystemEmailTemplateResponse template, ApplicationAmendmentRequestEntity amendment, UserEntity beneficiary) { Map subjectPlaceholders = new HashMap<>(); String firstName = beneficiary.getFirstName() != null ? beneficiary.getFirstName() : ""; String lastName = beneficiary.getLastName() != null ? beneficiary.getLastName() : ""; String beneficiaryName = String.join(" ", firstName, lastName).trim(); subjectPlaceholders.put("{{amendment_id}}", amendment.getId().toString()); subjectPlaceholders.put("{{beneficiary_name}}", beneficiaryName); return Utils.replacePlaceholders(template.getSubject(), subjectPlaceholders); } private String prepareBody(SystemEmailTemplateResponse template, ApplicationAmendmentRequestEntity amendment, UserEntity beneficiary) { Map bodyPlaceholders = new HashMap<>(); bodyPlaceholders.put("{{amendment_id}}", amendment.getId().toString()); if (amendment.getStartDate() != null && amendment.getResponseDays() != null) { LocalDateTime dueDate = amendment.getStartDate().plusDays(amendment.getResponseDays()); bodyPlaceholders.put("{{amendment_due_date}}", DateTimeUtil.formatLocalDateTime(dueDate, GepafinConstant.DD_MM_YYYY)); } else { bodyPlaceholders.put("{{amendment_due_date}}", "Not available"); } return Utils.replacePlaceholders(template.getHtmlContent(), bodyPlaceholders); } public ApplicationEvaluationEntity calculateEndDateAndSuspensionDays(ApplicationEvaluationEntity applicationEvaluationEntity){ LocalDateTime currentDate=DateTimeUtil.DateServerToUTC(LocalDateTime.now()); LocalDateTime endDate=currentDate.plusDays(applicationEvaluationEntity.getRemainingDays()); Long suspendedDays = ChronoUnit.DAYS.between(applicationEvaluationEntity.getStopDateTime(), currentDate); ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); applicationEvaluationEntity.setEndDate(endDate); if(applicationEvaluationEntity.getSuspendedDays() == null) { applicationEvaluationEntity.setSuspendedDays(0L); } applicationEvaluationEntity.setSuspendedDays(applicationEvaluationEntity.getSuspendedDays()+suspendedDays); ApplicationEvaluationEntity applicationEvaluation = applicationEvaluationRepository.save(applicationEvaluationEntity); /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(applicationEvaluation).build()); return applicationEvaluation; } private GetAllAmendmentResponseBean initializeGetAllBasicResponse(ApplicationAmendmentRequestEntity entity) { GetAllAmendmentResponseBean response = new GetAllAmendmentResponseBean(); ApplicationEntity applicationEntity = entity.getApplicationEvaluationEntity().getAssignedApplicationsEntity().getApplication(); response.setId(entity.getId()); response.setApplicationId(entity.getApplicationId()); response.setApplicationEvaluationId(entity.getApplicationEvaluationEntity().getId()); response.setNote(entity.getNote()); response.setStatus(ApplicationAmendmentRequestEnum.valueOf(entity.getStatus())); response.setResponseDays(entity.getResponseDays()); response.setInternalNote(entity.getInternalNote()); LocalDateTime startDate = entity.getStartDate(); response.setStartDate(startDate); response.setExpirationDate(entity.getEndDate()); response.setEvaluationEndDate(entity.getApplicationEvaluationEntity().getEndDate()); response.setIsSendEmail(entity.getIsEmail()); response.setIsSendNotification(entity.getIsNotification()); ApplicationEntity application = applicationService.validateApplication(entity.getApplicationId()); response.setCallEmail(application.getCall().getEmail()); response.setCallName(application.getCall().getName()); UserEntity userEntity = userService.validateUser(application.getUserId()); response.setBeneficiaryName(buildBeneficiaryName(userEntity)); CompanyEntity company = companyService.validateCompany(application.getCompanyId()); response.setCompanyName(company.getCompanyName()); Long protocolNumber = entity.getProtocol() != null ? entity.getProtocol().getProtocolNumber() : null; response.setProtocolNumber(protocolNumber); return response; } private void softDeleteDocument(Long documentId) { documentService.deleteFile(documentId); } // public PageableResponseBean> getApplicationAmendmentByPaginnation(Long userId, ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { // Integer pageNo = null; // Integer pageLimit = null; // if (applicationAmendmentPaginationRequestBean.getGlobalFilters() != null) { // pageNo = applicationAmendmentPaginationRequestBean.getGlobalFilters().getPage(); // pageLimit = applicationAmendmentPaginationRequestBean.getGlobalFilters().getLimit(); // } // if (pageLimit == null || pageLimit <= 0) { // pageLimit = GepafinConstant.DEFAULT_PAGE_LIMIT; // } // if (pageNo == null || pageNo <= 0) { // pageNo = GepafinConstant.DEFAULT_PAGE; // } // Specification spec = searchPagination(userId,applicationAmendmentPaginationRequestBean); // Page entityPage = applicationAmendmentRequestRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); // // // List applicationResponses = entityPage.getContent().stream() // .map(application -> { // ApplicationAmendmentRequestResponse response = convertEntityToResponse(application,false); // return response; // }) // .collect(Collectors.toList()); // // // PageableResponseBean> pageableResponseBean = new PageableResponseBean<>(); // pageableResponseBean.setBody(applicationResponses); // pageableResponseBean.setCurrentPage(entityPage.getNumber() + 1); // Page numbers typically start from 0, so add 1 for user-friendly indexing // pageableResponseBean.setTotalPages(entityPage.getTotalPages()); // pageableResponseBean.setTotalRecords(entityPage.getTotalElements()); // pageableResponseBean.setPageSize(entityPage.getSize()); // // return pageableResponseBean; // } // // public Specification searchPagination(Long userId,ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { // return (root, query, criteriaBuilder) -> { // // List predicates = getPredicates(applicationAmendmentPaginationRequestBean, criteriaBuilder, root,userId); // SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); // // if (applicationAmendmentPaginationRequestBean .getGlobalFilters() != null // && applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy() != null && // applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getColumnName() != null && Boolean.FALSE.equals( // isEmpty(applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getColumnName()))) { // sortBy.setColumnName(applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getColumnName()); // sortBy.setSortDesc(true); // if (applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getSortDesc() != null) { // sortBy.setSortDesc(applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getSortDesc()); // } // } // // query.orderBy(criteriaBuilder.desc(root.get(sortBy.getColumnName()))); // if (Boolean.FALSE.equals(sortBy.getSortDesc())) { // query.orderBy(criteriaBuilder.asc(root.get(sortBy.getColumnName()))); // } // return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getRestriction(); // }; // } // // // private List getPredicates(ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean, // CriteriaBuilder criteriaBuilder, Root root,Long userId) { // // Integer year = null; // String search = null; // if (amendmentPaginationRequestBean.getGlobalFilters() != null) { // year = amendmentPaginationRequestBean.getGlobalFilters().getYear(); // search = amendmentPaginationRequestBean.getGlobalFilters().getSearch(); // } // List predicates = new ArrayList<>(); // // if (year != null && year > 0) { // int filterYear = amendmentPaginationRequestBean.getGlobalFilters().getYear(); // //// Create LocalDateTime boundaries for the start and end of the year // LocalDateTime startOfYear = LocalDateTime.of(filterYear, 1, 1, 0, 0); // LocalDateTime endOfYear = LocalDateTime.of(filterYear, 12, 31, 23, 59, 59); // //// Add the range comparison to filter records within the year // predicates.add(criteriaBuilder.between(root.get(GepafinConstant.CREATED_DATE), startOfYear, endOfYear)); // // } // // Search in `title` and `message` (if search term is provided) // if (search != null && !search.isEmpty()) { // Predicate notePredicate = criteriaBuilder.like( // criteriaBuilder.upper(root.get(GepafinConstant.NOTE)), // "%" + search.toUpperCase() + "%" // ); // predicates.add(criteriaBuilder.or(notePredicate)); // Predicate internalNotePredicate = criteriaBuilder.like( // criteriaBuilder.upper(root.get(GepafinConstant.INTERNAL_NOTE)), // "%" + search.toUpperCase() + "%" // ); // predicates.add(criteriaBuilder.or(internalNotePredicate)); // } // // // Filter by `status` (if status list is provided) // if (amendmentPaginationRequestBean.getStatus() != null && !amendmentPaginationRequestBean.getStatus().isEmpty()) { // List statusValues = amendmentPaginationRequestBean.getStatus().stream() // .map(ApplicationAmendmentRequestEnum::name) // Convert enum to string // .toList(); // predicates.add(root.get(GepafinConstant.STATUS).in(statusValues)); // } // if(Boolean.TRUE.equals(validator.checkIsBeneficiary()) || Boolean.TRUE.equals(validator.checkIsConfidi())) { // predicates.add(root.get("applicationEvaluationEntity").get("assignedApplicationsEntity").get("application").get("userId").in(userId)); // } // else { // predicates.add(root.get("applicationEvaluationEntity").get("assignedApplicationsEntity").get("userId").in(userId)); // } // // return predicates; // // } public PageableResponseBean> getApplicationAmendmentByPaginationByView(Long userId, ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { Integer pageNo = null; Integer pageLimit = null; if (applicationAmendmentPaginationRequestBean.getGlobalFilters() != null) { pageNo = applicationAmendmentPaginationRequestBean.getGlobalFilters().getPage(); pageLimit = applicationAmendmentPaginationRequestBean.getGlobalFilters().getLimit(); } if (pageLimit == null || pageLimit <= 0) { pageLimit = GepafinConstant.DEFAULT_PAGE_LIMIT; } if (pageNo == null || pageNo <= 0) { pageNo = GepafinConstant.DEFAULT_PAGE; } Specification spec = searchPaginationByView(userId,applicationAmendmentPaginationRequestBean); Page entityPage = applicationAmendmentRequestViewRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); List applicationAmendmentRequestViewResponses = entityPage.getContent().stream() .map(amendmentRequestView -> { ApplicationAmendmentRequestViewResponse response = convertAmendmentEntityToApplicationAmendmentRequestViewResponse(amendmentRequestView); return response; }) .collect(Collectors.toList()); PageableResponseBean> pageableResponseBean = new PageableResponseBean<>(); pageableResponseBean.setBody(applicationAmendmentRequestViewResponses); pageableResponseBean.setCurrentPage(entityPage.getNumber() + 1); // Page numbers typically start from 0, so add 1 for user-friendly indexing pageableResponseBean.setTotalPages(entityPage.getTotalPages()); pageableResponseBean.setTotalRecords(entityPage.getTotalElements()); pageableResponseBean.setPageSize(entityPage.getSize()); return pageableResponseBean; } public Specification searchPaginationByView(Long userId,ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { return (root, query, criteriaBuilder) -> { List predicates = getPredicatesByView(applicationAmendmentPaginationRequestBean, criteriaBuilder, root,userId); SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); if (applicationAmendmentPaginationRequestBean .getGlobalFilters() != null && applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy() != null && applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getColumnName() != null && Boolean.FALSE.equals( isEmpty(applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getColumnName()))) { sortBy.setColumnName(applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getColumnName()); sortBy.setSortDesc(true); if (applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getSortDesc() != null) { sortBy.setSortDesc(applicationAmendmentPaginationRequestBean.getGlobalFilters().getSortBy().getSortDesc()); } } query.orderBy(criteriaBuilder.desc(root.get(sortBy.getColumnName()))); if (Boolean.FALSE.equals(sortBy.getSortDesc())) { query.orderBy(criteriaBuilder.asc(root.get(sortBy.getColumnName()))); } return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getRestriction(); }; } private List getPredicatesByView(ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean, CriteriaBuilder criteriaBuilder, Root root,Long userId) { Integer year = null; String search = null; Map filters = new HashMap<>(); if (amendmentPaginationRequestBean.getGlobalFilters() != null) { year = amendmentPaginationRequestBean.getGlobalFilters().getYear(); search = amendmentPaginationRequestBean.getGlobalFilters().getSearch(); } if (amendmentPaginationRequestBean.getFilters() != null) { filters = amendmentPaginationRequestBean.getFilters(); } List predicates = new ArrayList<>(); if (year != null && year > 0) { int filterYear = amendmentPaginationRequestBean.getGlobalFilters().getYear(); // Create LocalDateTime boundaries for the start and end of the year LocalDateTime startOfYear = LocalDateTime.of(filterYear, 1, 1, 0, 0); LocalDateTime endOfYear = LocalDateTime.of(filterYear, 12, 31, 23, 59, 59); // Add the range comparison to filter records within the year predicates.add(criteriaBuilder.between(root.get(GepafinConstant.CREATED_DATE), startOfYear, endOfYear)); } if (search != null && !search.isEmpty()) { List searchPredicates = new ArrayList<>(); searchPredicates.add(criteriaBuilder.like( criteriaBuilder.upper(root.get(GepafinConstant.CALL_NAME)), "%" + search.toUpperCase() + "%" )); searchPredicates.add(criteriaBuilder.like( criteriaBuilder.upper(root.get(GepafinConstant.COMPANY_NAME)), "%" + search.toUpperCase() + "%" )); // Uncomment these if needed // searchPredicates.add(criteriaBuilder.like( // criteriaBuilder.upper(root.get(GepafinConstant.NOTE)), // "%" + search.toUpperCase() + "%" // )); // // searchPredicates.add(criteriaBuilder.like( // criteriaBuilder.upper(root.get(GepafinConstant.INTERNAL_NOTE)), // "%" + search.toUpperCase() + "%" // )); Predicate finalPredicate = criteriaBuilder.or(searchPredicates.toArray(new Predicate[0])); predicates.add(finalPredicate); } Utils.applyFiltersByPagination(root, criteriaBuilder, predicates, filters); // Filter by `status` (if status list is provided) if (amendmentPaginationRequestBean.getStatus() != null && !amendmentPaginationRequestBean.getStatus().isEmpty()) { List statusValues = amendmentPaginationRequestBean.getStatus().stream() .map(ApplicationAmendmentRequestEnum::name) // Convert enum to string .toList(); predicates.add(root.get(GepafinConstant.STATUS).in(statusValues)); } boolean isBeneficiaryOrConfidi = validator.checkIsBeneficiary() || validator.checkIsConfidi(); boolean isPreInstructor = validator.checkIsPreInstructor(); boolean isInstructorManagerWithPersonalRecords = validator.checkIsInstructorManager() && Boolean.TRUE.equals(amendmentPaginationRequestBean.getPersonalRecords()); if (isBeneficiaryOrConfidi) { predicates.add(root.get(GepafinConstant.APPLICATION_USER_ID).in(userId)); } else if (isPreInstructor || isInstructorManagerWithPersonalRecords) { predicates.add(root.get(GepafinConstant.ASSIGNED_USER_ID).in(userId)); } return predicates; } public ApplicationAmendmentRequestViewResponse convertAmendmentEntityToApplicationAmendmentRequestViewResponse(ApplicationAmendmentRequestView applicationAmendmentRequestView){ ApplicationAmendmentRequestViewResponse applicationAmendmentRequestViewResponse=new ApplicationAmendmentRequestViewResponse(); applicationAmendmentRequestViewResponse.setId(applicationAmendmentRequestView.getId()); applicationAmendmentRequestViewResponse.setApplicationId(applicationAmendmentRequestView.getApplicationId()); applicationAmendmentRequestViewResponse.setProtocolNumber(applicationAmendmentRequestView.getProtocolNumber()); applicationAmendmentRequestViewResponse.setCallName(applicationAmendmentRequestView.getCallName()); applicationAmendmentRequestViewResponse.setCompanyName(applicationAmendmentRequestView.getCompanyName()); applicationAmendmentRequestViewResponse.setStartDate(applicationAmendmentRequestView.getStartDate()); applicationAmendmentRequestViewResponse.setExpirationDate(applicationAmendmentRequestView.getExpirationDate()); applicationAmendmentRequestViewResponse.setAssigendUserName(applicationAmendmentRequestView.getAssigendUserName()); applicationAmendmentRequestViewResponse.setStatus(applicationAmendmentRequestView.getStatus()); applicationAmendmentRequestViewResponse.setEmailSendResponse(applicationAmendmentRequestView.getEmailSendResponse()); return applicationAmendmentRequestViewResponse; } private void saveEmailSendResponse(EmailSendResponse newResponses, ApplicationAmendmentRequestEntity amendment) { List mergedResponses = Utils.mergeEmailSendResponses(amendment.getEmailSendResponse(), newResponses); amendment.setEmailSendResponse(mergedResponses); applicationAmendmentRequestRepository.save(amendment); } }