package net.gepafin.tendermanagement.dao; import jakarta.persistence.criteria.*; 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.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; 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.AssignedApplicationViewResponse; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.model.response.PageableResponseBean; import net.gepafin.tendermanagement.model.util.SortBy; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsViewRepository; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CompanyService; import net.gepafin.tendermanagement.service.UserService; 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.springframework.beans.factory.annotation.Autowired; 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.util.*; import java.util.stream.Collectors; 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 AssignedApplicationsDao { @Autowired private ApplicationService applicationService; @Autowired private ApplicationRepository applicationRepository; @Autowired private AssignedApplicationsRepository assignedApplicationsRepository; @Autowired private UserService userService; @Autowired private Validator validator; @Autowired private ApplicationEvaluationDao applicationEvaluationDao; @Autowired private CompanyService companyService; @Autowired private LoggingUtil loggingUtil; @Autowired private HttpServletRequest request; @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; @Autowired private AssignedApplicationsViewRepository assignedApplicationsViewRepository; public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest) { log.info("Assigning application to pre-Instructor with details: {}", applicationId, userId); AssignedApplicationsEntity assignedApplications = assignedApplicationsRepository.findByApplicationIdAndIsDeletedFalse(applicationId).orElse(null); if (assignedApplications != null && assignedApplications.getUserId().equals(userId)) { log.warn("Application ID={} is already assigned to User ID={}", applicationId, userId); throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); } else if(assignedApplications != null) { log.info("Reassigning Application ID={} from User ID={} to User ID={}", applicationId, assignedApplications.getUserId(), userId); assignedApplications = reassignApplication(userId, assignedByUser, assignedApplications); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignedApplications); log.info("Application re-assigned succesfully {}", assignApplicationToInstructorResponse); return assignApplicationToInstructorResponse; } ApplicationEntity application = applicationService.validateApplication(applicationId); if (Boolean.FALSE.equals(ApplicationStatusTypeEnum.SUBMIT.getValue().equals(application.getStatus()))) { log.warn("Invalid application status for assignment. Application ID={}, Current Status={}", applicationId, application.getStatus()); throw new CustomValidationException( Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.INVALID_APPLICATION_STATUS) ); } ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(application); application.setStatus(ApplicationStatusTypeEnum.EVALUATION.getValue()); applicationRepository.save(application); log.info("Application status updated to EVALUATION for Application ID={}", applicationId); /** 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(application).build()); UserEntity user = userService.validateUser(userId); AssignedApplicationsEntity assignment = createAssignmentEntity(application, user.getId(), assignedByUser, assignedApplicationsRequest); applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, new ApplicationEvaluationRequest(), assignment.getId()); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignment); log.info("Application assigned succesfully {}", assignApplicationToInstructorResponse); return assignApplicationToInstructorResponse; } private AssignedApplicationsEntity reassignApplication(Long userId, UserEntity assignedByUser, AssignedApplicationsEntity assignedApplication) { log.info("Starting reassignment for AssignedApplication ID={}, from User ID={} to User ID={}, Assigned By User ID={}", assignedApplication.getId(), assignedApplication.getUserId(), userId, assignedByUser.getId()); AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplication); setIfUpdated(assignedApplication::getAssignedBy, assignedApplication::setAssignedBy, assignedByUser.getId()); setIfUpdated(assignedApplication::getUserId, assignedApplication::setUserId, userId); assignedApplication.setAssignedAt(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); assignedApplication.setStatus(AssignedApplicationEnum.AWAITING.getValue()); Optional entityOptional = applicationEvaluationRepository.findByAssignedApplicationsEntity_IdAndIsDeletedFalse(assignedApplication.getId()); if(entityOptional.isPresent()) { ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(entityOptional.get()); setIfUpdated(entityOptional.get()::getUserId, entityOptional.get()::setUserId, userId); applicationEvaluationRepository.save(entityOptional.get()); /** This code is responsible for adding a version history log for the "Create Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(entityOptional.get()).build()); log.info("Updated ApplicationEvaluationEntity for AssignedApplication ID={}", assignedApplication.getId()); }; assignedApplication = assignedApplicationsRepository.save(assignedApplication); /** This code is responsible for adding a version history log for the "Create Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAssignedApplicationEntity).newData(assignedApplication).build()); log.info("Reassignment completed for AssignedApplication ID={}, new User ID={}", assignedApplication.getId(), userId); return assignedApplication; } public AssignedApplicationsEntity createAssignmentEntity(ApplicationEntity application, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest) { AssignedApplicationsEntity assignApplication = new AssignedApplicationsEntity(); assignApplication.setApplication(application); assignApplication.setAssignedBy(assignedByUser.getId()); assignApplication.setUserId(userId); assignApplication.setStatus(AssignedApplicationEnum.AWAITING.getValue()); assignApplication.setNote(assignedApplicationsRequest.getNote()); assignApplication.setIsDeleted(false); assignApplication.setAssignedAt(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); AssignedApplicationsEntity assignedApplicationsEntity = saveAssignedApplication(assignApplication, null, VersionActionTypeEnum.INSERT); return assignedApplicationsEntity; } public AssignedApplicationsEntity saveAssignedApplication(AssignedApplicationsEntity assignedApplicationsEntity, AssignedApplicationsEntity oldAssignedApplicationEntity, VersionActionTypeEnum actionTypeEnum) { AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.save(assignedApplicationsEntity); /** This code is responsible for adding a version history log for the "Create Application" operation. **/ loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(actionTypeEnum).oldData(oldAssignedApplicationEntity).newData(assignedApplication).build()); return assignedApplication; } public AssignedApplicationsResponse convertEntityToResponse(AssignedApplicationsEntity assignedApplications) { AssignedApplicationsResponse assignedApplicationsResponse = new AssignedApplicationsResponse(); assignedApplicationsResponse.setId(assignedApplications.getId()); assignedApplicationsResponse.setApplicationId(assignedApplications.getApplication().getId()); ApplicationEntity application = applicationService.validateApplication(assignedApplications.getApplication().getId()); String callName = application.getCall() != null ? application.getCall().getName() : ""; Optional applicationEvaluationEntity=applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(application.getId()); LocalDateTime callEndDate = application.getCall().getEndDate(); LocalDateTime callStartDate = application.getCall().getStartDate(); Long protocolNumber = (application.getProtocol() != null && application.getProtocol().getProtocolNumber() != null) ? application.getProtocol().getProtocolNumber() : 0; LocalDateTime submissionDate = application.getSubmissionDate(); UserEntity userEntity = userService.validateUser(application.getUserId()); String firstName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getFirstName() : null; String lastName = userEntity.getBeneficiary() != null ? userEntity.getBeneficiary().getLastName() : null; String beneficiaryName = (firstName != null && !firstName.isBlank() ? firstName : "") + (lastName != null && !lastName.isBlank() ? " " + lastName : ""); beneficiaryName = beneficiaryName.isBlank() ? "" : beneficiaryName; assignedApplicationsResponse.setAssignedBy(assignedApplications.getAssignedBy()); assignedApplicationsResponse.setUserId(assignedApplications.getUserId()); assignedApplicationsResponse.setCreatedDate(assignedApplications.getCreatedDate()); assignedApplicationsResponse.setUpdatedDate(assignedApplications.getUpdatedDate()); assignedApplicationsResponse.setNote(assignedApplications.getNote()); assignedApplicationsResponse.setStatus(AssignedApplicationEnum.valueOf(assignedApplications.getStatus())); assignedApplicationsResponse.setAssignedAt(assignedApplications.getAssignedAt()); assignedApplicationsResponse.setProtocolNumber(protocolNumber); assignedApplicationsResponse.setCallName(callName); CompanyEntity company=companyService.validateCompany(application.getCompanyId()); assignedApplicationsResponse.setCompanyName(company.getCompanyName()); assignedApplicationsResponse.setBeneficiaryName(beneficiaryName); assignedApplicationsResponse.setSubmissionDate(submissionDate); assignedApplicationsResponse.setCallEndDate(callEndDate); assignedApplicationsResponse.setCallStartDate(callStartDate); assignedApplicationsResponse.setEvaluationVersion(EvaluationVersionEnum.valueOf(application.getCall().getEvaluationVersion())); if(applicationEvaluationEntity.isPresent()){ assignedApplicationsResponse.setEvaluationEndDate(applicationEvaluationEntity.get().getEndDate()); } assignedApplicationsResponse.setNumberOfCheck(application.getCall().getNumberOfCheck()); assignedApplicationsResponse.setAppointmentTemplateId(application.getCall().getAppointmentTemplateId()); assignedApplicationsResponse.setNdg(application.getNdg()); assignedApplicationsResponse.setAppointmentId(application.getAppointmentId()); assignedApplicationsResponse.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(application.getStatus())); return assignedApplicationsResponse; } public AssignedApplicationsEntity validateAssignedApplication(Long id) { AssignedApplicationsEntity assignedApplication = assignedApplicationsRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> { log.warn("AssignedApplication not found or deleted for ID: {}", id); return new ResourceNotFoundException( Status.NOT_FOUND, Translator.toLocale(GepafinConstant.ASSIGNED_APPLICATION_NOT_FOUND_MSG) ); }); return assignedApplication; } public void deleteById(HttpServletRequest request, Long id) { log.info("Deleting assigned application with ID: {}", id); AssignedApplicationsEntity assignedApplicationsEntity = validateAssignedApplication(id); validator.validatePreInstructor(request, assignedApplicationsEntity.getUserId()); AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplicationsEntity); assignedApplicationsEntity.setIsDeleted(true); assignedApplicationsEntity = saveAssignedApplication(assignedApplicationsEntity, oldAssignedApplicationEntity, VersionActionTypeEnum.SOFT_DELETE); log.info("Soft-delete completed for AssignedApplication ID: {} by User ID: {}", id, assignedApplicationsEntity.getUserId()); } public List getAllAssignedApplications(HttpServletRequest request, Long userId,List statusList) { log.info("Fetching all assigned applications. Filtered target userId: {}", userId); UserEntity user = validator.validateUser(request); 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(user.getHub().getId() ,userId,statusList); List assignedApplicationsEntityList = assignedApplicationsRepository.findAll(spec); return assignedApplicationsEntityList.stream() .map(entity -> convertEntityToResponse(entity)) .collect(Collectors.toList()); } private Specification search(Long hubId, Long userId,List statusList) { return (root, query, builder) -> { Predicate predicate = builder.isFalse(root.get("isDeleted")); if (userId != null) { predicate = builder.and(predicate, builder.equal(root.get("userId"), userId)); } if (statusList != null && !statusList.isEmpty()) { List statusNames = statusList.stream() .map(Enum::name) .collect(Collectors.toList()); predicate = builder.and(predicate, root.get("status").in(statusNames)); } query.orderBy( builder.desc(builder.isNotNull(root.get(GepafinConstant.ASSIGNED_AT))), builder.desc(root.get(GepafinConstant.ASSIGNED_AT)) ); predicate = builder.and(predicate, builder.equal(root.get("application").get("hubId"), hubId)); return predicate; }; } public AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, UpdateAssignedApplicationRequest updateRequest) { UserEntity updatedByUser = validator.validateUser(request); log.info("Updating assigned application with ID: {}", id); AssignedApplicationsEntity existingAssignment = validateAssignedApplication(id); validator.validatePreInstructor(request, existingAssignment.getUserId()); AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(existingAssignment); 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); AssignedApplicationsResponse response = convertEntityToResponse(updatedAssignment); log.info("Assigned application updated successfully: {}", response); return response; } public AssignedApplicationsResponse getAssignedApplicationById(HttpServletRequest request, Long id) { log.info("Fetching assigned application with ID: {}", id); AssignedApplicationsEntity assignedApplication = validateAssignedApplication(id); validator.validatePreInstructor(request, assignedApplication.getUserId()); AssignedApplicationsResponse response = convertEntityToResponse(assignedApplication); log.info("Assigned application fetched successfully: {}", response); return response; } public PageableResponseBean> getAllAssignedApplicationsByPagination(UserEntity user, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean,Long userId) { log.info("Fetching assigned applications. Requestor: {}, Target User: {}", user.getId(), userId); Integer pageNo = null; Integer pageLimit = null; if (assignedApplicationPageableRequestBean.getGlobalFilters() != null) { pageNo = assignedApplicationPageableRequestBean.getGlobalFilters().getPage(); pageLimit = assignedApplicationPageableRequestBean.getGlobalFilters().getLimit(); } if (pageLimit == null || pageLimit <= 0) { pageLimit = GepafinConstant.DEFAULT_PAGE_LIMIT; } if (pageNo == null || pageNo <= 0) { pageNo = GepafinConstant.DEFAULT_PAGE; } Long hubId=user.getHub().getId(); Specification spec = searchByPagination( assignedApplicationPageableRequestBean,hubId,userId); Page entityPage = assignedApplicationsViewRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); // Prepare the response List assignedApplicationsResponses = entityPage.getContent().stream() .map(this::getAssignedApplicationResponseByView) .collect(Collectors.toList()); PageableResponseBean> pageableResponseBean = new PageableResponseBean<>(); pageableResponseBean.setBody(assignedApplicationsResponses); pageableResponseBean.setCurrentPage(entityPage.getNumber() + 1); pageableResponseBean.setTotalPages(entityPage.getTotalPages()); pageableResponseBean.setTotalRecords(entityPage.getTotalElements()); pageableResponseBean.setPageSize(entityPage.getSize()); return pageableResponseBean; } public Specification searchByPagination(AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean, Long hubId,Long userId) { return (root, query, criteriaBuilder) -> { List predicates = getPredicates(assignedApplicationPageableRequestBean, criteriaBuilder, root, hubId,userId); SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); if (assignedApplicationPageableRequestBean.getGlobalFilters() != null && assignedApplicationPageableRequestBean.getGlobalFilters().getSortBy() != null && assignedApplicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName() != null && Boolean.FALSE.equals( isEmpty(assignedApplicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName()))) { sortBy.setColumnName(assignedApplicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName()); sortBy.setSortDesc(true); if (assignedApplicationPageableRequestBean.getGlobalFilters().getSortBy().getSortDesc() != null) { sortBy.setSortDesc(assignedApplicationPageableRequestBean.getGlobalFilters().getSortBy().getSortDesc()); } } // Path sortPath; // Join applicationJoin = root.join(GepafinConstant.APPLICATION, JoinType.LEFT); // // if (GepafinConstant.APPLICATION_ID.equals(sortBy.getColumnName())) { // sortPath = root.join(GepafinConstant.APPLICATION, JoinType.LEFT).get(GepafinConstant.ID); // Join ApplicationEntity and sort by application.id // } // else if (GepafinConstant.PROTOCOL_NUMBER.equals(sortBy.getColumnName())) { // Join protocolJoin = applicationJoin.join(GepafinConstant.PROTOCOL, JoinType.LEFT); // sortPath = protocolJoin.get(GepafinConstant.PROTOCOL_NUMBER); // } // else { // sortPath = root.get(sortBy.getColumnName()); // Sorting by a field in AmendmentEntity // } // query.orderBy(criteriaBuilder.desc(sortPath)); // if (Boolean.FALSE.equals(sortBy.getSortDesc())) { // query.orderBy(criteriaBuilder.asc(sortPath)); // } // return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getRestriction(); Path sortPath = root.get(sortBy.getColumnName()); // All fields are accessible directly in the view query.orderBy(sortBy.getSortDesc() ? criteriaBuilder.desc(sortPath) : criteriaBuilder.asc(sortPath)); return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getRestriction(); }; } private List getPredicates(AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean, CriteriaBuilder criteriaBuilder, Root root,Long hubId,Long userId) { Integer year = null; String search = null; Map filters = new HashMap<>(); if (assignedApplicationPageableRequestBean.getGlobalFilters() != null) { year = assignedApplicationPageableRequestBean.getGlobalFilters().getYear(); search = assignedApplicationPageableRequestBean.getGlobalFilters().getSearch(); } if (assignedApplicationPageableRequestBean.getFilters() != null) { filters = assignedApplicationPageableRequestBean.getFilters(); } List predicates = new ArrayList<>(); Boolean isBeneficiary = validator.checkIsBeneficiary(); if (userId!=null) { predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.USER_ID), userId)); } if (year != null && year > 0) { int filterYear = assignedApplicationPageableRequestBean.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 titlePredicate = criteriaBuilder.like( // criteriaBuilder.upper(root.get(GepafinConstant.NOTE)), // "%" + search.toUpperCase() + "%" // ); // predicates.add(criteriaBuilder.or(titlePredicate)); // } if (search != null && !search.trim().isEmpty()) { String pattern = "%" + search.toUpperCase() + "%"; List searchPredicates = new ArrayList<>(); searchPredicates.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(GepafinConstant.CALL_NAME)), pattern)); searchPredicates.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(GepafinConstant.COMPANY_NAME)), pattern)); searchPredicates.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(GepafinConstant.STATUS)), pattern)); searchPredicates.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(GepafinConstant.NDG_STRING)), pattern)); searchPredicates.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(GepafinConstant.APPOINTMENT_ID)), pattern)); searchPredicates.add(criteriaBuilder.like(criteriaBuilder.upper(root.get(GepafinConstant.APPLICATION_STATUS)), pattern)); // Convert numeric fields to string for search (optional and DB-specific; otherwise exact match) try { Long searchLong = Long.parseLong(search); searchPredicates.add(criteriaBuilder.equal(root.get(GepafinConstant.APPLICATION_ID), searchLong)); searchPredicates.add(criteriaBuilder.equal(root.get(GepafinConstant.PROTOCOL_NUMBER), searchLong)); } catch (NumberFormatException ignored) { // Ignore if search is not a number } predicates.add(criteriaBuilder.or(searchPredicates.toArray(new Predicate[0]))); } // Filter by `status` (if status list is provided) if (assignedApplicationPageableRequestBean.getStatus() != null && !assignedApplicationPageableRequestBean.getStatus().isEmpty()) { List statusValues = assignedApplicationPageableRequestBean.getStatus().stream() .map(AssignedApplicationEnum::name) // Convert enum to string .toList(); predicates.add(root.get(GepafinConstant.STATUS).in(statusValues)); } predicates.add(criteriaBuilder.isFalse(root.get(GepafinConstant.IS_DELETED))); predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.HUB_ID), hubId)); Utils.applyFiltersByPagination(root, criteriaBuilder, predicates, filters); return predicates; } private AssignedApplicationViewResponse getAssignedApplicationResponseByView(AssignedApplicationsView view) { AssignedApplicationViewResponse response = new AssignedApplicationViewResponse(); response.setId(view.getId()); response.setUserId(view.getUserId()); response.setStatus(AssignedApplicationEnum.valueOf(view.getStatus())); response.setApplicationId(view.getApplicationId()); response.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(view.getApplicationStatus())); response.setSubmissionDate(view.getSubmissionDate()); response.setEvaluationEndDate(view.getEvaluationEndDate()); response.setNdg(view.getNdg()); response.setAppointmentId(view.getAppointmentId()); response.setProtocolNumber(view.getProtocolNumber()); response.setCallName(view.getCallName()); response.setCompanyName(view.getCompanyName()); response.setCreatedDate(view.getCreatedDate()); response.setUpdatedDate(view.getUpdatedDate()); response.setEmailSendResponse(view.getEmailSendResponse()); response.setAssignedUserName(view.getAssignedUserName()); return response; } public AssignedApplicationsResponse updateAssignedApplicationStatus(HttpServletRequest request, Long assignedApplicationId, AssignedApplicationEnum status) { log.info("Request received to update status of assigned application. AssignedApplicationId: {}, NewStatus: {}", assignedApplicationId, status); AssignedApplicationsEntity assignedApplication = validateAssignedApplication(assignedApplicationId); validator.validatePreInstructor(request, assignedApplication.getUserId()); AssignedApplicationsEntity oldAssignedApplicationEntity = Utils.getClonedEntityForData(assignedApplication); assignedApplication.setStatus(status.getValue()); AssignedApplicationsEntity updatedAssignment = saveAssignedApplication(assignedApplication, oldAssignedApplicationEntity, VersionActionTypeEnum.UPDATE); log.info("Assigned application status updated successfully. AssignedApplicationId: {}, OldStatus: {}, NewStatus: {}", assignedApplicationId, oldAssignedApplicationEntity.getStatus(), status.getValue()); return convertEntityToResponse(updatedAssignment); } private void applyFilters(Root root, CriteriaBuilder criteriaBuilder, List predicates, Map filters) { if (Boolean.FALSE.equals(filters.isEmpty())) { for (Map.Entry entry : filters.entrySet()) { String fieldName = entry.getKey(); FilterCriteria filterCriteria = entry.getValue(); Object value = filterCriteria.getValue(); MatchModeEnum matchMode = filterCriteria.getMatchMode(); if (value != null && matchMode != null) { Path fieldPath = getFieldPath(root, fieldName); if (fieldPath != null) { Utils.applyStringFilter(fieldPath, criteriaBuilder, predicates, value, matchMode); Utils.applyNumberFilter(fieldPath, criteriaBuilder, predicates, value, matchMode); Utils.applyDateFilter(fieldPath, criteriaBuilder, predicates, value, matchMode,root); } } } } } private Path getFieldPath(Root root, String fieldName) { try { return switch (fieldName) { case GepafinConstant.APPLICATION_ID -> root.get(GepafinConstant.APPLICATION).get(GepafinConstant.ID); case GepafinConstant.PROTOCOL_NUMBER-> root.get(GepafinConstant.APPLICATION).get(GepafinConstant.PROTOCOL).get(GepafinConstant.PROTOCOL_NUMBER); default -> root.get(fieldName); }; } catch (IllegalArgumentException e) { return null; } } }