diff --git a/pom.xml b/pom.xml index 9c84bcc4..daa067ba 100644 --- a/pom.xml +++ b/pom.xml @@ -258,6 +258,17 @@ + + + + + + com.sun.mail + jakarta.mail + 2.0.1 + + + diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 4f15580c..5c849a47 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -101,6 +101,7 @@ public class GepafinConstant { public static final String STATUS_SAME_ERROR = "status.same.error"; public static final String INVALID_STATUS_CHANGE_FROM_DRAFT = "invalid.status.change.from.draft"; public static final String INVALID_STATUS_CHANGE_FROM_PUBLISH = "invalid.status.change.from.publish"; + public static final String INVALID_STATUS_CHANGE_FROM_PUBLISH_TO_DRAFT = "invalid.status.change.from.publish.to.draft"; public static final String STATUS_CANNOT_BE_CHANGED = "status.cannot.be.changed"; public static final String PUBLISHED_CALL_NOT_UPDATE = "published.call.not.update"; public static final String INVALID_USER = "invalid_user"; @@ -136,7 +137,9 @@ public class GepafinConstant { public static final String UPDATING_FORM_VALUE_IMPACT_ON_FLOW = "updating.form.value.impact.on.flow"; public static final String APPLICATION_IS_INCOMPLETE_MSG = "application.is.incomplete"; public static final String AUTHORIZATION = "Authorization"; - public static final String CHECK_VATNUMBER_V2_NEW_URL = "https://imprese.openapi.it/advance"; + public static final String CHECK_VATNUMBER_URL_V1 = "https://imprese.openapi.it/advance"; + public static final String CHECK_VATNUMBER_URL_V2 = "https://company.openapi.com/IT-advanced"; + public static final String VAT_CHECK_API_VERSION = "VAT_CHECK_API_VERSION"; public static final String VALIDATION_FIELD_CUSTOM = "validation.field.custom"; public static final String VALIDATION_CODICE_FISCALE = "validation.codice.fiscale"; public static final String VALIDATION_CAP = "validation.cap"; @@ -529,6 +532,11 @@ public class GepafinConstant { public static final String GET_FIELD_VALUE="getFieldValue"; public static final String GET_REPORT_ENABLE="getReportEnable"; public static final String GET_REPORT_HEADER="getReportHeader"; + + public static final String APPOINTMENT_ID="appointmentId"; + public static final String APPLICATION_STATUS="applicationStatus"; + + public static final String RINALDO_EMAIL = "rinaldo.bonazzo@bflows.net"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index a766d1a5..daa4391b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -134,6 +134,12 @@ public class ApplicationAmendmentRequestDao { @Autowired private ApplicationEvaluationFormRepository applicationEvaluationFormRepository; + @Autowired + private ApplicationAmendmentRequestViewRepository applicationAmendmentRequestViewRepository; + + @Autowired + private ApplicationDao applicationDao; + public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); @@ -1268,7 +1274,122 @@ public class ApplicationAmendmentRequestDao { documentService.deleteFile(documentId); } - public PageableResponseBean> getApplicationAmendmentByPaginnation(Long userId, ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { +// 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) { @@ -1281,20 +1402,20 @@ public class ApplicationAmendmentRequestDao { if (pageNo == null || pageNo <= 0) { pageNo = GepafinConstant.DEFAULT_PAGE; } - Specification spec = searchPagination(userId,applicationAmendmentPaginationRequestBean); - Page entityPage = applicationAmendmentRequestRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); + Specification spec = searchPaginationByView(userId,applicationAmendmentPaginationRequestBean); + Page entityPage = applicationAmendmentRequestViewRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); - List applicationResponses = entityPage.getContent().stream() - .map(application -> { - ApplicationAmendmentRequestResponse response = convertEntityToResponse(application,false); + List applicationAmendmentRequestViewResponses = entityPage.getContent().stream() + .map(amendmentRequestView -> { + ApplicationAmendmentRequestViewResponse response = convertAmendmentEntityToApplicationAmendmentRequestViewResponse(amendmentRequestView); return response; }) .collect(Collectors.toList()); - PageableResponseBean> pageableResponseBean = new PageableResponseBean<>(); - pageableResponseBean.setBody(applicationResponses); + 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()); @@ -1302,11 +1423,10 @@ public class ApplicationAmendmentRequestDao { return pageableResponseBean; } - - public Specification searchPagination(Long userId,ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { + public Specification searchPaginationByView(Long userId,ApplicationAmendmentPaginationRequestBean applicationAmendmentPaginationRequestBean) { return (root, query, criteriaBuilder) -> { - List predicates = getPredicates(applicationAmendmentPaginationRequestBean, criteriaBuilder, root,userId); + List predicates = getPredicatesByView(applicationAmendmentPaginationRequestBean, criteriaBuilder, root,userId); SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); if (applicationAmendmentPaginationRequestBean .getGlobalFilters() != null @@ -1329,15 +1449,19 @@ public class ApplicationAmendmentRequestDao { } - private List getPredicates(ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean, - CriteriaBuilder criteriaBuilder, Root root,Long userId) { + 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) { @@ -1351,19 +1475,37 @@ public class ApplicationAmendmentRequestDao { 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)), + List searchPredicates = new ArrayList<>(); + + searchPredicates.add(criteriaBuilder.like( + criteriaBuilder.upper(root.get(GepafinConstant.CALL_NAME)), "%" + search.toUpperCase() + "%" - ); - predicates.add(criteriaBuilder.or(notePredicate)); - Predicate internalNotePredicate = criteriaBuilder.like( - criteriaBuilder.upper(root.get(GepafinConstant.INTERNAL_NOTE)), + )); + + searchPredicates.add(criteriaBuilder.like( + criteriaBuilder.upper(root.get(GepafinConstant.COMPANY_NAME)), "%" + search.toUpperCase() + "%" - ); - predicates.add(criteriaBuilder.or(internalNotePredicate)); + )); + + // 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()) { @@ -1372,14 +1514,33 @@ public class ApplicationAmendmentRequestDao { .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)); + 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()); + return applicationAmendmentRequestViewResponse; + } + + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java index d6b66527..e95e1c8b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationDao.java @@ -132,8 +132,6 @@ public class ApplicationDao { @Value("${rinaldo_email}") private String rinaldoEmail; - @Value("${carlo_email}") - private String carloEmail; @Value("${call.id}") private String callId; @@ -198,6 +196,9 @@ public class ApplicationDao { @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; + @Autowired + private ApplicationViewRepository applicationViewRepository; + @Autowired private ApplicationFormViewRepository applicationFormViewRepository; @@ -976,6 +977,13 @@ public class ApplicationDao { applicationEntity.setStatus(status.getValue()); log.info("Status updated to DRAFT for applicationId: " + applicationId); } + if (status.equals(ApplicationStatusTypeEnum.AWAITING) && Boolean.TRUE.equals(applicationEntity.getStatus().equals(ApplicationStatusTypeEnum.READY.getValue()))) { + ApplicationSignedDocumentEntity applicationSignedDocument = applicationSignedDocumentRepository.findByApplicationIdAndStatus(applicationId, + ApplicationSignedDocumentStatusEnum.ACTIVE.getValue()); + deleteSignedDocumentFromS3(applicationSignedDocument); + applicationEntity.setStatus(status.getValue()); + log.info("Status updated to AWAITING for applicationId: " + applicationId); + } applicationEntity = applicationRepository.save(applicationEntity); log.info("Application status updated successfully | applicationId: {}, newStatus: {}", applicationId, applicationEntity.getStatus()); @@ -1150,24 +1158,6 @@ public class ApplicationDao { EmailLogRequest emailLogRequest=emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(),RecipientTypeEnum.PROPERTIES,null,userEntity.getEmail(),userEntity.getId(),applicationEntity.getId(),null,applicationEntity.getCall().getId()); -// mailUtil.sendByMailGun(subject, body, List.of(defaultSystemReceiverEmail), null); -// mailUtil.sendByMailGun(subject, body, List.of(gepafinEmail), null); -// mailUtil.sendByMailGun(subject, body, List.of(rinaldoEmail), null); -// if(Boolean.TRUE.equals(hub.getUniqueUuid().equals(defaultHubUuid))) { -// if (validator.isProductionProfileActivated()) { -// emailLogRequest.setRecipientEmails(carloEmail); -//// mailUtil.sendByMailGun(subject, body, List.of(carloEmail), null); -// emailNotificationDao.sendMail(hub.getId(), subject, body, List.of(carloEmail),emailLogRequest); -// } -// List listDefaultSystemReceiverEmail = Arrays.stream(defaultSystemReceiverEmail.split(",")) -// .map(String::trim) -// .filter(email -> !email.isEmpty()) -// .toList(); -// -// emailLogRequest.setRecipientEmails(defaultSystemReceiverEmail); -// emailNotificationDao.sendMail(hub.getId(), subject, body, listDefaultSystemReceiverEmail, emailLogRequest); -// } - List hubEmails = Arrays.stream(hub.getEmail().split(",")) .map(String::trim) .filter(email -> !email.isEmpty()) @@ -1192,9 +1182,7 @@ public class ApplicationDao { ApplicationSignedDocumentEntity oldApplicationSingedDocumentData = Utils.getClonedEntityForData(applicationSignedDocument); if (applicationSignedDocument != null) { - throw new CustomValidationException(Status.BAD_REQUEST, Translator.toLocale(GepafinConstant.APPLICATION_ALREADY_ASSIGNED)); - // applicationSignedDocument.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); - // applicationSignedDocumentRepository.save(applicationSignedDocument); + deleteSignedDocumentFromS3(applicationSignedDocument); } UploadFileOnAmazonS3Response uploadFileOnAmazonS3 = uploadFileOnAmazonS3ForUserSignedDocument(file, applicationEntity.getCall().getId(), applicationId); applicationSignedDocument = new ApplicationSignedDocumentEntity(); @@ -1217,6 +1205,19 @@ public class ApplicationDao { return convertApplicationSignedDocumentToApplicationSignedDocumentResponse(applicationSignedDocument); } + public void deleteSignedDocumentFromS3(ApplicationSignedDocumentEntity applicationSignedDocumentEntity){ + ApplicationSignedDocumentEntity oldApplicationSignedDocument = Utils.getClonedEntityForData(applicationSignedDocumentEntity); + String oldS3Path = applicationSignedDocumentEntity.getFilePath(); + String newS3Path = s3ConfigBean.generateDocumentPathForOther(DocOtherSourceTypeEnum.DELETED_USER_SIGNED_DOCUMENT,applicationSignedDocumentEntity.getApplication().getCall().getId(),applicationSignedDocumentEntity.getApplication().getId(),0L); + + UploadFileOnAmazonS3Response response = amazonS3Service.moveFile(applicationSignedDocumentEntity.getFileName(), oldS3Path, newS3Path); + applicationSignedDocumentEntity.setStatus(ApplicationSignedDocumentStatusEnum.INACTIVE.getValue()); + applicationSignedDocumentEntity.setFileName(response.getFileName()); + applicationSignedDocumentEntity.setFilePath(response.getFilePath()); + + applicationSignedDocumentRepository.save(applicationSignedDocumentEntity); + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.SOFT_DELETE).oldData(oldApplicationSignedDocument).newData(applicationSignedDocumentEntity).build()); + } private void validateFileTypeForCall(MultipartFile file, ApplicationEntity applicationEntity) { List validCallIds = Arrays.asList(callId.split(",")); @@ -1460,279 +1461,22 @@ public class ApplicationDao { } } - public PageableResponseBean> getAllApplicationByPagination(UserEntity userEntity, Long callId, Long companyId, ApplicationPageableRequestBean applicationPageableRequestBean) { - Integer pageNo = null; - Integer pageLimit = null; - UserWithCompanyEntity userWithCompany= userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), companyId).orElse(null); - Long userWithCompanyId = userWithCompany!=null?userWithCompany.getId():null; - if (applicationPageableRequestBean.getGlobalFilters() != null) { - pageNo = applicationPageableRequestBean.getGlobalFilters().getPage(); - pageLimit = applicationPageableRequestBean.getGlobalFilters().getLimit(); - } - if (pageLimit == null || pageLimit <= 0) { - pageLimit = GepafinConstant.DEFAULT_PAGE_LIMIT; - } - if (pageNo == null || pageNo <= 0) { - pageNo = GepafinConstant.DEFAULT_PAGE; - } - Specification spec = search(callId,companyId, userWithCompanyId, applicationPageableRequestBean, userEntity); - Page entityPage = applicationRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); - // Prepare the response - - - List applicationResponses = entityPage.getContent().stream() - .map(application -> { - ApplicationResponse response = getApplicationResponse(application); - 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 search(Long callId, Long companyId, Long userWithCompanyId, ApplicationPageableRequestBean applicationPageableRequestBean, UserEntity userEntity) { - return (root, query, criteriaBuilder) -> { - - List predicates = getPredicates(applicationPageableRequestBean, criteriaBuilder, root, callId,companyId, userWithCompanyId, userEntity); - SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); - - if (applicationPageableRequestBean.getGlobalFilters() != null - && applicationPageableRequestBean.getGlobalFilters().getSortBy() != null && - applicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName() != null && Boolean.FALSE.equals( - isEmpty(applicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName()))) { - sortBy.setColumnName(applicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName()); - sortBy.setSortDesc(true); - if (applicationPageableRequestBean.getGlobalFilters().getSortBy().getSortDesc() != null) { - sortBy.setSortDesc(applicationPageableRequestBean.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(ApplicationPageableRequestBean applicationPageableRequestBean, - CriteriaBuilder criteriaBuilder, Root root, Long callId,Long companyId, Long userWithCompanyId, UserEntity userEntity) { - - Integer year = null; - String search = null; - Integer daysRange = null; - Map filters = new HashMap<>(); - if (applicationPageableRequestBean.getGlobalFilters() != null) { - year = applicationPageableRequestBean.getGlobalFilters().getYear(); - search = applicationPageableRequestBean.getGlobalFilters().getSearch(); - daysRange = applicationPageableRequestBean.getDaysRange(); - } - if (applicationPageableRequestBean.getFilters() != null) { - filters = applicationPageableRequestBean.getFilters(); - } - List predicates = new ArrayList<>(); - -// Boolean isBeneficiary = validator.checkIsBeneficiary(); - if (Boolean.TRUE.equals(validator.checkIsBeneficiary()) || Boolean.TRUE.equals(validator.checkIsConfidi())) { - predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.USER_ID), userEntity.getId())); - } - if (year != null && year > 0) { - int filterYear = applicationPageableRequestBean.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.COMMENTS)), - "%" + search.toUpperCase() + "%" - ); -// Predicate protocolPredicate = criteriaBuilder.like( -// criteriaBuilder.function( -// "TO_CHAR", -// String.class, -// criteriaBuilder.function("CAST", String.class, root.get(GepafinConstant.PROTOCOL).get(GepafinConstant.PROTOCOL_NUMBER)) -// ), -// "%" + search + "%" -// ); - - Predicate callNamePredicate =criteriaBuilder.like( - criteriaBuilder.upper(root.get(GepafinConstant.CALL).get(GepafinConstant.NAME)), // Adjust field name - "%" + search.toUpperCase() + "%" - ); - -// predicates.add(criteriaBuilder.or(protocolPredicate)); - predicates.add(criteriaBuilder.or(callNamePredicate)); - predicates.add(criteriaBuilder.or(titlePredicate)); - } - - // Filter by `status` (if status list is provided) - if (applicationPageableRequestBean.getStatus() != null && !applicationPageableRequestBean.getStatus().isEmpty()) { - List statusValues = applicationPageableRequestBean.getStatus().stream() - .map(ApplicationStatusTypeEnum::name) // Convert enum to string - .toList(); - predicates.add(root.get(GepafinConstant.STATUS).in(statusValues)); - } - - if (callId != null) { - CallEntity call = callService.validateCall(callId); - predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.CALL).get(GepafinConstant.ID), callId)); - } - - // Optional companyId filter - if (userWithCompanyId != null) { - predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.USER_WITH_COMPANY).get(GepafinConstant.ID), userWithCompanyId)); - } - if (companyId != null) { - predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.COMPANY_ID), companyId)); - } - - if (daysRange != null && daysRange >= 0) { - LocalDateTime today = LocalDateTime.now(); - LocalDateTime pastDate = today.minusDays(daysRange); - predicates.add(criteriaBuilder.between(root.get(GepafinConstant.CREATED_DATE), pastDate, today)); - } - applyFilters(root, criteriaBuilder, predicates, filters); - - predicates.add(criteriaBuilder.isFalse(root.get(GepafinConstant.IS_DELETED))); - - predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.HUB_ID), userEntity.getHub().getId())); - - - return predicates; - } - 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) { - applyStringFilter(fieldPath, criteriaBuilder, predicates, value, matchMode); - applyNumberFilter(fieldPath, criteriaBuilder, predicates, value, matchMode); - applyDateFilter(fieldPath, criteriaBuilder, predicates, value, matchMode,root); - } - } - } - } - } - - private void applyStringFilter(Path fieldPath, CriteriaBuilder criteriaBuilder, List predicates, Object value, MatchModeEnum matchMode) { - if (value instanceof String) { - String valueStr = (String) value; - if (fieldPath.getJavaType().equals(String.class)) { - MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue()); - switch (mode) { - case CONTAINS -> - predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), "%" + valueStr.toLowerCase() + "%")); - case EQUALS -> predicates.add(criteriaBuilder.equal(fieldPath, valueStr)); - case STARTSWITH -> - predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), valueStr.toLowerCase() + "%")); - case ENDSWITH -> - predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), "%" + valueStr.toLowerCase())); - } - } - } - } - - private void applyNumberFilter(Path fieldPath, CriteriaBuilder criteriaBuilder, List predicates, Object value, MatchModeEnum matchMode) { - if (Number.class.isAssignableFrom(fieldPath.getJavaType())) { - Number numberValue = null; - if (value instanceof Number) { - numberValue = (Number) value; - } - MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue()); - switch (mode) { - case EQUALS -> predicates.add(criteriaBuilder.equal(fieldPath, numberValue)); - } - } - } - - - - - private void applyDateFilter(Path fieldPath, CriteriaBuilder criteriaBuilder, List predicates, Object value, MatchModeEnum matchMode, Root root) { - if (fieldPath.getJavaType().equals(LocalDateTime.class)) { - // Convert input string: Replace 'T' with space - String formattedValue = value.toString().replace("T", " "); - - // Handle timezones and UTC (`Z` or `+HH:mm`) - if (formattedValue.contains("Z") || formattedValue.matches(".*[+-]\\d{2}:\\d{2}$")) { - OffsetDateTime offsetDateTime = OffsetDateTime.parse(value.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME); - formattedValue = offsetDateTime.toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")); - } - - // Check if more than 3 decimal places exist - if (formattedValue.contains(".")) { - int dotIndex = formattedValue.indexOf("."); - if (formattedValue.length() > dotIndex + 4) { - formattedValue = formattedValue.substring(0, dotIndex + 4); // Keep only 3 decimals - } - } else { - formattedValue += ".000"; // Ensure 3 decimals - } - - // Define correct date-time format - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); - - // Parse the formatted value into LocalDateTime - LocalDateTime dateTimeValue = LocalDateTime.parse(formattedValue, formatter); - - // Extract only the date portion - LocalDate dateValue = dateTimeValue.toLocalDate(); - - // Convert database field to LocalDate for date-only comparison - Expression dateField = criteriaBuilder.function("DATE", LocalDate.class, fieldPath); - - MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue()); - - switch (mode) { - case DATEIS -> predicates.add(criteriaBuilder.equal(dateField, dateValue)); - case DATEISNOT -> predicates.add(criteriaBuilder.notEqual(dateField, dateValue)); - case BEFORE -> predicates.add(criteriaBuilder.lessThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue))); - case AFTER -> predicates.add(criteriaBuilder.greaterThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue))); - } - } - } - - - - - private Path getFieldPath(Root root, String fieldName) { - try { - return switch (fieldName) { - case GepafinConstant.CALL_ID -> root.get(GepafinConstant.CALL).get(GepafinConstant.ID); - case GepafinConstant.CALL_TITLE -> root.get(GepafinConstant.CALL).get(GepafinConstant.NAME); - case GepafinConstant.CALL_END_DATE -> root.get(GepafinConstant.CALL).get(GepafinConstant.END_DATE); - case GepafinConstant.CALL_END_TIME -> root.get(GepafinConstant.CALL).get(GepafinConstant.END_TIME); - case GepafinConstant.MODIFIED_DATE -> root.get(GepafinConstant.CALL).get(GepafinConstant.UPDATED_DATE); - case GepafinConstant.PROTOCOL_NUMBER-> root.get(GepafinConstant.PROTOCOL).get(GepafinConstant.PROTOCOL_NUMBER); - default -> root.get(fieldName); - }; - } catch (IllegalArgumentException e) { - return null; - } - } +// private Path getFieldPath(Root root, String fieldName) { +// try { +// return switch (fieldName) { +//// case GepafinConstant.CALL_ID -> root.get(GepafinConstant.CALL).get(GepafinConstant.ID); +//// case GepafinConstant.CALL_TITLE -> root.get(GepafinConstant.CALL).get(GepafinConstant.NAME); +//// case GepafinConstant.CALL_END_DATE -> root.get(GepafinConstant.CALL).get(GepafinConstant.END_DATE); +//// case GepafinConstant.CALL_END_TIME -> root.get(GepafinConstant.CALL).get(GepafinConstant.END_TIME); +//// case GepafinConstant.MODIFIED_DATE -> root.get(GepafinConstant.CALL).get(GepafinConstant.UPDATED_DATE); +//// case GepafinConstant.PROTOCOL_NUMBER-> root.get(GepafinConstant.PROTOCOL).get(GepafinConstant.PROTOCOL_NUMBER); +// default -> root.get(fieldName); +// }; +// } catch (IllegalArgumentException e) { +// return null; +// } +// } public void checkCallEndDate(CallEntity call) { @@ -1890,6 +1634,195 @@ public class ApplicationDao { } return application; } + public PageableResponseBean> getAllApplicationByPaginationByView(UserEntity userEntity, Long callId, Long companyId, ApplicationPageableRequestBean applicationPageableRequestBean) { + Integer pageNo = null; + Integer pageLimit = null; + + UserWithCompanyEntity userWithCompany= userWithCompanyRepository.findByUserIdAndCompanyIdAndIsDeletedFalse(userEntity.getId(), companyId).orElse(null); + Long userWithCompanyId = userWithCompany!=null?userWithCompany.getId():null; + if (applicationPageableRequestBean.getGlobalFilters() != null) { + pageNo = applicationPageableRequestBean.getGlobalFilters().getPage(); + pageLimit = applicationPageableRequestBean.getGlobalFilters().getLimit(); + } + if (pageLimit == null || pageLimit <= 0) { + pageLimit = GepafinConstant.DEFAULT_PAGE_LIMIT; + } + if (pageNo == null || pageNo <= 0) { + pageNo = GepafinConstant.DEFAULT_PAGE; + } + Specification spec = searchByView(callId,companyId, userWithCompanyId, applicationPageableRequestBean, userEntity); + Page entityPage = applicationViewRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); + // Prepare the response + + + List applicationResponses = entityPage.getContent().stream() + .map(application -> { + ApplicationResponse response = getApplicationResponseByView(application); + 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 searchByView(Long callId, Long companyId, Long userWithCompanyId, ApplicationPageableRequestBean applicationPageableRequestBean, UserEntity userEntity) { + return (root, query, criteriaBuilder) -> { + + List predicates = getPredicatesByView(applicationPageableRequestBean, criteriaBuilder, root, callId,companyId, userWithCompanyId, userEntity); + SortBy sortBy = new SortBy(GepafinConstant.CREATED_DATE, true); + + if (applicationPageableRequestBean.getGlobalFilters() != null + && applicationPageableRequestBean.getGlobalFilters().getSortBy() != null && + applicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName() != null && Boolean.FALSE.equals( + isEmpty(applicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName()))) { + sortBy.setColumnName(applicationPageableRequestBean.getGlobalFilters().getSortBy().getColumnName()); + sortBy.setSortDesc(true); + if (applicationPageableRequestBean.getGlobalFilters().getSortBy().getSortDesc() != null) { + sortBy.setSortDesc(applicationPageableRequestBean.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(ApplicationPageableRequestBean applicationPageableRequestBean, + CriteriaBuilder criteriaBuilder, Root root, Long callId,Long companyId, Long userWithCompanyId, UserEntity userEntity) { + + Integer year = null; + String search = null; + Integer daysRange = null; + Map filters = new HashMap<>(); + if (applicationPageableRequestBean.getGlobalFilters() != null) { + year = applicationPageableRequestBean.getGlobalFilters().getYear(); + search = applicationPageableRequestBean.getGlobalFilters().getSearch(); + daysRange = applicationPageableRequestBean.getDaysRange(); + } + if (applicationPageableRequestBean.getFilters() != null) { + filters = applicationPageableRequestBean.getFilters(); + } + List predicates = new ArrayList<>(); + +// Boolean isBeneficiary = validator.checkIsBeneficiary(); + if (Boolean.TRUE.equals(validator.checkIsBeneficiary()) || Boolean.TRUE.equals(validator.checkIsConfidi())) { + predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.USER_ID), userEntity.getId())); + } + if (year != null && year > 0) { + int filterYear = applicationPageableRequestBean.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()) { + String searchPattern = "%" + search.toUpperCase() + "%"; + + Predicate titlePredicate = criteriaBuilder.like( + criteriaBuilder.upper(root.get(GepafinConstant.COMMENTS)), + searchPattern + ); + + Predicate callTitlePredicate = criteriaBuilder.like( + criteriaBuilder.upper(root.get(GepafinConstant.CALL_TITLE)), + searchPattern + ); + Predicate callNamePredicate = criteriaBuilder.like( + criteriaBuilder.upper(root.get(GepafinConstant.CALL_NAME)), + searchPattern + ); + Predicate companyName = criteriaBuilder.like( + criteriaBuilder.upper(root.get(GepafinConstant.COMPANY_NAME)), + searchPattern + ); + + // Combine them using a single `or()` + Predicate finalPredicate = criteriaBuilder.or(titlePredicate, callTitlePredicate,callNamePredicate,companyName); + predicates.add(finalPredicate); + } + + // Filter by `status` (if status list is provided) + if (applicationPageableRequestBean.getStatus() != null && !applicationPageableRequestBean.getStatus().isEmpty()) { + List statusValues = applicationPageableRequestBean.getStatus().stream() + .map(ApplicationStatusTypeEnum::name) // Convert enum to string + .toList(); + predicates.add(root.get(GepafinConstant.STATUS).in(statusValues)); + } + + if (callId != null) { + CallEntity call = callService.validateCall(callId); + predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.CALL_ID), callId)); + } + + // Optional companyId filter + if (userWithCompanyId != null) { + predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.USER_WITH_COMPANY_ID), userWithCompanyId)); + } + if (companyId != null) { + predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.COMPANY_ID), companyId)); + } + + if (daysRange != null && daysRange >= 0) { + LocalDateTime today = LocalDateTime.now(); + LocalDateTime pastDate = today.minusDays(daysRange); + predicates.add(criteriaBuilder.between(root.get(GepafinConstant.CREATED_DATE), pastDate, today)); + } + Utils.applyFiltersByPagination(root, criteriaBuilder, predicates, filters); + + predicates.add(criteriaBuilder.isFalse(root.get(GepafinConstant.IS_DELETED))); + + predicates.add(criteriaBuilder.equal(root.get(GepafinConstant.HUB_ID), userEntity.getHub().getId())); + + + return predicates; + } + + private ApplicationResponse getApplicationResponseByView(ApplicationView applicationView) { + ApplicationResponse responseBean = new ApplicationResponse(); + List flowEdgesList = flowEdgesRepository.findByCallId(applicationView.getCallId()); + Long totalFormSteps = flowFormDao.calculateTotalSteps(flowEdgesList); + Long completedSteps = Long.valueOf(flowFormDao.getCompletedStepsByView(applicationView.getId(), false)); + Integer progress = calculateProgress(totalFormSteps, completedSteps); + responseBean.setId(applicationView.getId()); + responseBean.setProgress(progress); + responseBean.setCallTitle(applicationView.getCallTitle()); + responseBean.setCallEndDate(applicationView.getCallEndDate()); + responseBean.setCallEndTime(applicationView.getCallEndTime()); + responseBean.setModifiedDate(applicationView.getModifiedDate()); + responseBean.setCallId(applicationView.getCallId()); + responseBean.setSubmissionDate(applicationView.getSubmissionDate()); + responseBean.setStatus(applicationView.getStatus()); + responseBean.setEvaluationVersion(EvaluationVersionEnum.valueOf(applicationView.getEvaluationVersion())); + responseBean.setComments(applicationView.getComments()); + responseBean.setCompanyId(applicationView.getCompanyId()); + responseBean.setAssignedUserId(applicationView.getAssignedUserId()); + responseBean.setAssignedUserName(applicationView.getAssignedUserName()); + responseBean.setCompanyName(applicationView.getCompanyName()); + responseBean.setProtocolNumber(applicationView.getProtocolNumber()); + responseBean.setAmountAccepted(applicationView.getAmountAccepted()); + responseBean.setAmountRequested(applicationView.getAmountRequested()); + responseBean.setDateAccepted(applicationView.getDateAccepted()); + responseBean.setDateRejected(applicationView.getDateRejected()); + return responseBean; + } + public List getApplicationFormData(Long callId) { List applicationFormViews=new ArrayList<>(); @@ -2199,4 +2132,6 @@ public class ApplicationDao { tableDataByApp.put(appId, flattenedAll); } } + + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java index 46af8a26..9f135199 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AppointmentDao.java @@ -720,9 +720,11 @@ public class AppointmentDao { // Build the appointment request body AppointmentCreationRequest appointmentCreationRequest = buildAppointmentCreationRequest(applicationId, createAppointmentRequest, appointmentTemplateId, templateRichiestaData); + log.info("AppointmentCreationRequest : {}", appointmentCreationRequest); String appointmentRequestBody = Utils.convertObjectToJson(appointmentCreationRequest); // Make API call to create the appointment + log.info("Context:{}, Authorization Token : {}, RequestBody : {}", context, authorizationToken, appointmentRequestBody); ResponseEntity appointmentResponse = appointmentApiService.createAppointment(authorizationToken, context, appointmentRequestBody); String appointmentId = extractAppointmentIdFromResponse(appointmentResponse); @@ -751,6 +753,7 @@ public class AppointmentDao { private String extractAppointmentIdFromResponse(ResponseEntity appointmentResponse) { if (appointmentResponse.getBody() != null) { + log.info("Appointment API Response : {}", appointmentResponse.getBody()); Map responseBody = (Map) appointmentResponse.getBody(); if (responseBody.containsKey(GepafinConstant.DATA_STRING)) { Map data = (Map) responseBody.get(GepafinConstant.DATA_STRING); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index c09c0fb6..17f18c9c 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -1,8 +1,6 @@ package net.gepafin.tendermanagement.dao; -import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Predicate; -import jakarta.persistence.criteria.Root; +import jakarta.persistence.criteria.*; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; @@ -16,12 +14,14 @@ 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; @@ -39,9 +39,7 @@ import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Component; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import static net.gepafin.tendermanagement.util.Utils.log; @@ -81,6 +79,9 @@ public class AssignedApplicationsDao { @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); @@ -301,7 +302,7 @@ public class AssignedApplicationsDao { log.info("Assigned application fetched successfully: {}", response); return response; } - public PageableResponseBean> getAllAssignedApplicationsByPagination(UserEntity user, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean,Long userId) { + public PageableResponseBean> getAllAssignedApplicationsByPagination(UserEntity user, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean,Long userId) { Integer pageNo = null; Integer pageLimit = null; if (assignedApplicationPageableRequestBean.getGlobalFilters() != null) { @@ -314,21 +315,15 @@ public class AssignedApplicationsDao { if (pageNo == null || pageNo <= 0) { pageNo = GepafinConstant.DEFAULT_PAGE; } - Specification spec = searchByPagination( assignedApplicationPageableRequestBean, user,userId); - Page entityPage = assignedApplicationsRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); + Specification spec = searchByPagination( assignedApplicationPageableRequestBean, user,userId); + Page entityPage = assignedApplicationsViewRepository.findAll(spec, PageRequest.of(pageNo - 1, pageLimit)); // Prepare the response - - List assignedApplicationsResponses = entityPage.getContent().stream() - .map(application -> { - AssignedApplicationsResponse response = convertEntityToResponse(application); - return response; - }) + List assignedApplicationsResponses = entityPage.getContent().stream() + .map(this::getAssignedApplicationResponseByView) .collect(Collectors.toList()); - - - PageableResponseBean> pageableResponseBean = new PageableResponseBean<>(); + PageableResponseBean> pageableResponseBean = new PageableResponseBean<>(); pageableResponseBean.setBody(assignedApplicationsResponses); pageableResponseBean.setCurrentPage(entityPage.getNumber() + 1); pageableResponseBean.setTotalPages(entityPage.getTotalPages()); @@ -338,7 +333,7 @@ public class AssignedApplicationsDao { return pageableResponseBean; } - public Specification searchByPagination(AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean, UserEntity userEntity,Long userId) { + public Specification searchByPagination(AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean, UserEntity userEntity,Long userId) { return (root, query, criteriaBuilder) -> { List predicates = getPredicates(assignedApplicationPageableRequestBean, criteriaBuilder, root, userEntity,userId); @@ -354,25 +349,47 @@ public class AssignedApplicationsDao { 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)); - 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(AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean, - CriteriaBuilder criteriaBuilder, Root root, UserEntity userEntity,Long userId) { + CriteriaBuilder criteriaBuilder, Root root, UserEntity userEntity,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(); @@ -391,12 +408,35 @@ public class AssignedApplicationsDao { } // 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.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) @@ -408,11 +448,31 @@ public class AssignedApplicationsDao { } predicates.add(criteriaBuilder.isFalse(root.get(GepafinConstant.IS_DELETED))); - + 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()); + return response; + } + public AssignedApplicationsResponse updateAssignedApplicationStatus(HttpServletRequest request, Long assignedApplicationId, AssignedApplicationEnum status) { AssignedApplicationsEntity assignedApplication = validateAssignedApplication(assignedApplicationId); @@ -423,4 +483,39 @@ public class AssignedApplicationsDao { AssignedApplicationsEntity updatedAssignment = saveAssignedApplication(assignedApplication, oldAssignedApplicationEntity, VersionActionTypeEnum.UPDATE); 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; + } + } + } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java index 94c586b9..fa02eac1 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CallDao.java @@ -124,6 +124,9 @@ public class CallDao { @Autowired private EvaluationFormDao evalualtionFormDao; + @Autowired + private ApplicationRepository applicationRepository; + public CallResponse createCallStep1(CreateCallRequestStep1 createCallRequest, UserEntity userEntity) { createCallRequest.setRegionId(userEntity.getRoleEntity().getRegion().getId()); CallEntity callEntity = convertToCallEntity(createCallRequest, userEntity); @@ -902,7 +905,7 @@ public class CallDao { public CallResponse updateCallStatus(CallEntity callEntity, CallStatusEnum statusReq) { CallEntity oldCallEntity = Utils.getClonedEntityForData(callEntity); CallStatusEnum currentStatus = CallStatusEnum.valueOf(callEntity.getStatus()); - validateStatusChange(currentStatus, statusReq); + validateStatusChange(currentStatus, statusReq, callEntity.getId()); callEntity.setStatus(statusReq.getValue()); callEntity = callRepository.save(callEntity); @@ -922,36 +925,37 @@ public class CallDao { return convertToCallResponseBean(callEntity); } - private void validateStatusChange(CallStatusEnum currentStatus, CallStatusEnum newStatus) { + private void validateStatusChange(CallStatusEnum currentStatus, CallStatusEnum newStatus, Long callId) { + if (currentStatus == newStatus) { - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.STATUS_SAME_ERROR)); + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.STATUS_SAME_ERROR)); } - switch (currentStatus) { - case DRAFT: - if (newStatus == CallStatusEnum.READY_TO_PUBLISH || newStatus == CallStatusEnum.PUBLISH) { - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_DRAFT)); - } - break; - case PUBLISH: - if (newStatus == CallStatusEnum.READY_TO_PUBLISH || newStatus == CallStatusEnum.DRAFT) { - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_PUBLISH)); - } - break; + case DRAFT: + if (newStatus == CallStatusEnum.READY_TO_PUBLISH || newStatus == CallStatusEnum.PUBLISH) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_DRAFT)); + } + break; - case EXPIRED: - throw new CustomValidationException(Status.VALIDATION_ERROR, - Translator.toLocale(GepafinConstant.STATUS_CANNOT_BE_CHANGED)); - case READY_TO_PUBLISH: - break; - default: - break; + case PUBLISH: + if (newStatus == CallStatusEnum.READY_TO_PUBLISH) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_PUBLISH)); + } + if (newStatus == CallStatusEnum.DRAFT && Boolean.TRUE.equals(applicationRepository.existsByCallId(callId))) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_STATUS_CHANGE_FROM_PUBLISH_TO_DRAFT)); + } + break; + case EXPIRED: + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.STATUS_CANNOT_BE_CHANGED)); + + case READY_TO_PUBLISH: + break; + default: + break; } } + public CallEntity validatePublishedCall(Long callId, Long hubId) { CallEntity callEntity= callRepository .findByIdAndStatusAndHubId(callId, CallStatusEnum.PUBLISH.getValue(), hubId); diff --git a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java index ca9c2621..91a589e7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/CompanyDao.java @@ -1,9 +1,7 @@ package net.gepafin.tendermanagement.dao; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.data.domain.Pageable; // Correct package -import java.util.EnumSet; import java.util.List; import java.util.Map; @@ -20,7 +18,6 @@ import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.FaqRepository; -import net.gepafin.tendermanagement.service.feignClient.VatCheckService; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.web.rest.api.errors.*; import org.apache.commons.lang3.StringUtils; @@ -37,7 +34,6 @@ import net.gepafin.tendermanagement.model.response.CompanyResponse; import net.gepafin.tendermanagement.service.UserService; import net.gepafin.tendermanagement.util.Utils; -import static net.gepafin.tendermanagement.util.Utils.convertObjectToJsonString; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @Component @@ -73,10 +69,6 @@ public class CompanyDao { private HttpServletRequest request; - @Autowired - private VatCheckService vatCheckService; // Service to call VAT API - - private static final String NOT_FOUND_JSON = "{\"data\": \"not found\"}"; public CompanyResponse createCompany(UserEntity userEntity, CompanyRequest companyRequest) { @@ -146,24 +138,7 @@ public class CompanyDao { loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(userWithCompany).build()); if (StringUtils.isEmpty(companyEntity.getJson())) { companyEntity.setJson(Utils.convertMapIntoJsonString(companyRequest.getVatCheckResponse())); - Map vatCheckResponse = companyRequest.getVatCheckResponse(); - Map data = (Map) vatCheckResponse.get("data"); - if (data != null) { - if (data.containsKey("dettaglio")) { - Map dettaglio = (Map) data.get("dettaglio"); - if (dettaglio != null) { - if (dettaglio.containsKey("codice_ateco")) { - Object codiceAtecoObj = dettaglio.get("codice_ateco"); - String codiceAteco = (codiceAtecoObj != null) ? codiceAtecoObj.toString() : null; - - if (codiceAteco != null) { - companyEntity.setCodiceAteco(codiceAteco); - } - } - } - } - } - + updateCodiceAtecoFieldWithNewJson(companyEntity); companyEntity = companyRepository.save(companyEntity); /** This code is responsible for adding a version history log for "updating company json field" operation. **/ @@ -193,25 +168,8 @@ public class CompanyDao { entity.setAnnualRevenue(request.getAnnualRevenue()); entity.setHub(userEntity.getHub()); entity.setJson(Utils.convertMapIntoJsonString(request.getVatCheckResponse())); - if (request.getVatCheckResponse() != null) { - Map vatCheckResponse = request.getVatCheckResponse(); - Map data = (Map) vatCheckResponse.get("data"); - if (data != null) { - if (data.containsKey("dettaglio")) { - Map dettaglio = (Map) data.get("dettaglio"); - if (dettaglio != null) { - if (dettaglio.containsKey("codice_ateco")) { - Object codiceAtecoObj = dettaglio.get("codice_ateco"); - String codiceAteco = (codiceAtecoObj != null) ? codiceAtecoObj.toString() : null; - - if (codiceAteco != null) { - entity.setCodiceAteco(codiceAteco); - } - } - } - } - } - } + updateCodiceAtecoFieldWithNewJson(entity); + return entity; } @@ -469,7 +427,7 @@ public class CompanyDao { log.info("Company ID {}: JSON field updated successfully.", company.getId()); // Extract and set codiceAteco field - updateCodiceAtecoField(company); + updateCodiceAtecoFieldWithNewJson(company); successfulUpdates++; } else { @@ -503,49 +461,89 @@ public class CompanyDao { private void updateCodiceAtecoField(CompanyEntity company) { Map vatCheckResponse = Utils.convertJsonStringToMap(company.getJson()); - if (vatCheckResponse != null && vatCheckResponse.containsKey("data")) { - Object dataObj = vatCheckResponse.get("data"); + if (vatCheckResponse == null) { + log.warn("Company ID {}: Invalid JSON response.", company.getId()); + return; + } - if (dataObj instanceof Map) { - Map dataMap = (Map) dataObj; - log.info("Company ID {}: Available keys inside 'data' -> {}", company.getId(), dataMap.keySet()); + Object dataObj = vatCheckResponse.get("data"); + if (!(dataObj instanceof Map dataMap)) { + log.warn("Company ID {}: 'data' is missing or not a valid object.", company.getId()); + return; + } - if (dataMap.containsKey("dettaglio")) { - Object dettaglioObj = dataMap.get("dettaglio"); + if (!dataMap.containsKey("dettaglio")) { + log.warn("Company ID {}: 'dettaglio' not present inside 'data'. Skipping codiceAteco update.", company.getId()); + return; + } - if (dettaglioObj instanceof Map) { - Map dettaglio = (Map) dettaglioObj; + Object dettaglioObj = dataMap.get("dettaglio"); + if (!(dettaglioObj instanceof Map dettaglio)) { + log.warn("Company ID {}: 'dettaglio' is not a valid object.", company.getId()); + return; + } - if (dettaglio.containsKey("codice_ateco")) { - Object codiceAtecoObj = dettaglio.get("codice_ateco"); + Object codiceAtecoObj = dettaglio.get("codice_ateco"); + if (!(codiceAtecoObj instanceof String codiceAteco) || codiceAteco.isEmpty()) { + log.warn("Company ID {}: 'codice_ateco' is missing, empty, or not a string.", company.getId()); + return; + } - if (codiceAtecoObj instanceof String) { - String codiceAteco = (String) codiceAtecoObj; + company.setCodiceAteco(codiceAteco); + logCodiceAtecoUpdate(company, codiceAteco); + } - if (codiceAteco != null && !codiceAteco.isEmpty()) { - company.setCodiceAteco(codiceAteco); - log.info("Company ID {}: codiceAteco updated to {}", company.getId(), codiceAteco); - } else { - log.warn("Company ID {}: codiceAteco is null or empty in the response.", company.getId()); - } - } else { - log.warn("Company ID {}: 'codice_ateco' is not a string, actual type: {}", company.getId(), codiceAtecoObj.getClass()); - } - } else { - log.warn("Company ID {}: 'dettaglio' does not contain 'codice_ateco' key.", company.getId()); - } - } else { - log.warn("Company ID {}: 'dettaglio' is not a Map, actual type: {}", company.getId(), dettaglioObj.getClass()); - } - } else { - log.warn("Company ID {}: 'dettaglio' section is missing inside 'data'!", company.getId()); - } - } else { - log.warn("Company ID {}: 'data' is not a Map, actual type: {}", company.getId(), dataObj.getClass()); - } + private void updateCodiceAtecoFieldWithNewJson(CompanyEntity company) { + if (company == null || company.getJson() == null || company.getJson().isEmpty()) { + log.warn("Company is null or JSON data is empty."); + return; + } + + Map companyDataMap = Utils.convertJsonStringToMap(company.getJson()); + if (companyDataMap == null) { + log.warn("Company ID {}: Failed to parse JSON data.", company.getId()); + return; + } + + // Extract 'data' section + Map dataMap = Utils.extractMap(companyDataMap, "data"); + Object dataObj = companyDataMap.get("data"); + + if (dataMap == null) { + log.warn("Company ID {}: 'data' section is missing or invalid in the JSON.", company.getId()); + return; + } + if (dataObj instanceof Map) { + // if data is a single object + updateCodiceAtecoField(company); } else { - log.warn("Company ID {}: 'data' section missing in the JSON response.", company.getId()); + // Extract 'atecoClassification' section + Map atecoClassificationMap = Utils.extractMap(dataMap, "atecoClassification"); + if (atecoClassificationMap == null) { + log.warn("Company ID {}: 'atecoClassification' section is missing or invalid.", company.getId()); + return; + } + + // Extract 'ateco' section + Map atecoMap = Utils.extractMap(atecoClassificationMap, "ateco"); + if (atecoMap == null) { + log.warn("Company ID {}: 'ateco' section is missing or invalid.", company.getId()); + return; + } + + // Extract and set 'code' + String atecoCode = Utils.extractString(atecoMap, "code"); + if (atecoCode != null && !atecoCode.isEmpty()) { + company.setCodiceAteco(atecoCode); + logCodiceAtecoUpdate(company, atecoCode); + } else { + log.warn("Company ID {}: 'code' inside 'ateco' is empty or missing.", company.getId()); + } } } + private static void logCodiceAtecoUpdate(CompanyEntity company, String atecoCode) { + + log.info("Company ID {}: codiceAteco updated to {}", company.getId(), atecoCode); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java index a3243c22..b39efce7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/DelegationDao.java @@ -209,7 +209,6 @@ public class DelegationDao { companyDao.validateCompany(companyId); companyDao.getUserWithCompany(userEntity.getId(), companyId); - validateFileType(file); UserWithCompanyEntity userWithCompanyEntity=companyService.getUserWithCompany(userEntity.getId(),companyId); UserCompanyDelegationEntity userCompanyDelegationEntity = userCompanyDelegationRepository .findByUserIdAndUserWithCompanyIdAndStatus(userEntity.getId(), userWithCompanyEntity.getId(), diff --git a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java index 185d1c62..171ccbfa 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/EmailNotificationDao.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.*; +import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; import net.gepafin.tendermanagement.enums.RecipientTypeEnum; import net.gepafin.tendermanagement.model.request.EmailConfig; import net.gepafin.tendermanagement.model.request.EmailLogRequest; @@ -15,6 +16,7 @@ import net.gepafin.tendermanagement.service.*; import net.gepafin.tendermanagement.service.impl.EmailService; import net.gepafin.tendermanagement.service.impl.EmailServiceFactory; import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.service.impl.SystemEmailService; import net.gepafin.tendermanagement.util.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -140,7 +142,9 @@ public class EmailNotificationDao { if (rinaldoEmail != null) { EmailLogRequest emailLogRequest = emailLogDao.createEmailLogRequest(systemEmailTemplateResponse.getEmailScenario(), RecipientTypeEnum.PROPERTIES,null , rinaldoEmail, userEntity.getId(), applicationEntity.getId(), amendmentId, applicationEntity.getCall().getId()); - sendMail(applicationEntity.getHubId(), subject, body, List.of(rinaldoEmail), emailLogRequest); + + //SMTP + sendMail(null, subject, body, List.of(rinaldoEmail), emailLogRequest); } if (applicationEvaluationEntity.isPresent()) { Long preInstructorId = applicationEvaluationEntity.get().getUserId(); // Assuming UserEntity has an email field @@ -275,10 +279,17 @@ public class EmailNotificationDao { public void sendMail(Long hubId, String subject, String body, List recipientEmails, EmailLogRequest emailLogRequest) { - EmailConfig emailConfig = retrieveEmailConfig(hubId); - EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); - emailService.sendEmail(subject, body, recipientEmails, emailConfig,emailLogRequest); -// emailService.sendEmail(subject, body, recipientEmails, emailConfig); + EmailConfig emailConfig = new EmailConfig(); + if (recipientEmails.stream().anyMatch(email -> email.equals(GepafinConstant.RINALDO_EMAIL))) { + emailConfig.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE.getValue()); + EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); + emailService.sendEmail(subject, body, recipientEmails, emailConfig, emailLogRequest); + } else { + emailConfig = retrieveEmailConfig(hubId); + EmailService emailService = emailServiceFactory.getEmailService(emailConfig.getEmailServiceType()); + emailService.sendEmail(subject, body, recipientEmails, emailConfig, emailLogRequest); + + } } public EmailConfig retrieveEmailConfig(Long hubId) { diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java index 2287850d..e516f23b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FlowFormDao.java @@ -368,6 +368,18 @@ public class FlowFormDao { } return getNextForm(currentFormEntity, applicationEntity); } - + public Integer getCompletedStepsByView(Long applicationId, Boolean isSendValidationError) { + Integer completedSteps=0; + List applicationFormList = applicationFormRepository.findByApplicationId(applicationId); + List applicationFormFieldEntities=new ArrayList<>(); + for (ApplicationFormEntity applicationFormEntity:applicationFormList){ + applicationFormFieldEntities=applicationFormFieldRepository.findByApplicationFormId(applicationFormEntity.getId()); + Boolean isCompleted=formDao.validateCompletedSteps(applicationFormFieldEntities, null, applicationFormEntity.getForm(), isSendValidationError); + if(Boolean.TRUE.equals(isCompleted)){ + completedSteps++; + } + } + return completedSteps; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java index 702a3b44..598f6477 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/FormDao.java @@ -511,7 +511,7 @@ public class FormDao { // Map customData=null; try { // Map vatCheckResponse = vatCheckDao.checkVatNumberApi(value); - vatCheckDao.checkVatNumberApi(value); + vatCheckDao.checkVatNumber(value); // if (Boolean.FALSE.equals(CollectionUtils.isEmpty(vatCheckResponse))) { // customData = vatCheckResponse; // } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java index 3a32373c..17b86d6e 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/NotificationDao.java @@ -1,10 +1,8 @@ package net.gepafin.tendermanagement.dao; import jakarta.persistence.criteria.CriteriaBuilder; -import jakarta.persistence.criteria.Expression; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; -import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; @@ -12,7 +10,6 @@ import net.gepafin.tendermanagement.entities.*; import net.gepafin.tendermanagement.enums.NotificationEnum; import net.gepafin.tendermanagement.enums.NotificationTypeEnum; import net.gepafin.tendermanagement.enums.RoleStatusEnum; -import net.gepafin.tendermanagement.model.request.GlobalFilters; import net.gepafin.tendermanagement.model.request.NotificationReq; import net.gepafin.tendermanagement.model.request.NotificationRequestBean; import net.gepafin.tendermanagement.model.response.NotificationResponse; @@ -28,22 +25,19 @@ import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; -import org.opensaml.xmlsec.signature.G; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.isEmpty; @@ -92,7 +86,7 @@ public class NotificationDao { log.info("Sending notification to user {} with content: {}", userId, notificationReq.getMessage()); List companyIds = notificationReq.getCompanyIds(); - if (companyIds == null || companyIds.isEmpty()) { + if (companyIds == null || companyIds.isEmpty() || companyIds.stream().allMatch(Objects::isNull)) { sendToUser(userId, notificationEntity); } else { sendToCompanies(userId, companyIds, notificationEntity); @@ -154,7 +148,7 @@ public class NotificationDao { notificationEntity.setUserId(notificationReq.getUserId()); notificationEntity.setStatus(NotificationEnum.UNREAD.getValue()); notificationEntity.setIsDeleted(Boolean.FALSE); - notificationEntity.setUserWithCompany(notificationReq.getUserWithCompanyEntity() != null ? notificationReq.getUserWithCompanyEntity() : null); + notificationEntity.setUserWithCompany(notificationReq.getUserWithCompanyEntity()); notificationEntity.setMessage(message); notificationEntity.setTitle(notificationReq.getTitle()); return notificationEntity; diff --git a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java index 4d74fb71..1c6869ad 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/VatCheckDao.java @@ -1,14 +1,15 @@ package net.gepafin.tendermanagement.dao; import feign.FeignException; -import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; -import net.gepafin.tendermanagement.entities.CompanyEntity; +import net.gepafin.tendermanagement.enums.VatCheckVersionTypeEnum; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; -import net.gepafin.tendermanagement.service.feignClient.VatCheckService; -import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.repositories.GlobalConfigRepository; +import net.gepafin.tendermanagement.service.feignClient.VatCheckV1Service; +import net.gepafin.tendermanagement.service.feignClient.VatCheckV2Service; import net.gepafin.tendermanagement.util.Utils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -20,32 +21,36 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import java.net.URI; +import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; @Component public class VatCheckDao { @Autowired - private VatCheckService vatCheckService; + private VatCheckV2Service vatCheckV2Service; - @Value("${vatCheckNewToken}") - public String vatCheckNewToken; + @Autowired + private VatCheckV1Service vatCheckV1Service; + + @Value("${vatCheckTokenV2}") + public String vatCheckTokenV2; + + @Value("${vatCheckTokenV1}") + public String vatCheckTokenV1; @Value("${isVatCheckGloballyDisabled}") public String isVatCheckGloballyDisabled; + @Autowired + private GlobalConfigRepository globalConfigRepository; + public final Logger log = LoggerFactory.getLogger(VatCheckDao.class); - @Autowired - private LoggingUtil loggingUtil; - - @Autowired - private HttpServletRequest request; - - public VatCheckResponseBean checkVatNumberApi(String vatNumber) { + public VatCheckResponseBean checkVatNumberV1(String vatNumber) { VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); vatCheckResponseBean.setValid(false); vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); @@ -53,28 +58,31 @@ public class VatCheckDao { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); return vatCheckResponseBean; } - Map responseBody = new HashMap<>(); try { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setContentType(MediaType.APPLICATION_JSON); - headers.set(GepafinConstant.AUTHORIZATION, "Bearer " + vatCheckNewToken); + headers.set(GepafinConstant.AUTHORIZATION, "Bearer " + vatCheckTokenV1); headers.add(org.apache.http.HttpHeaders.USER_AGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0"); - URI baseUrl = URI.create(GepafinConstant.CHECK_VATNUMBER_V2_NEW_URL); - ResponseEntity> response = vatCheckService.checkVatNumber(baseUrl, vatNumber, headers); - + URI baseUrl = URI.create(GepafinConstant.CHECK_VATNUMBER_URL_V1); + ResponseEntity> response = vatCheckV1Service.checkVatNumber(baseUrl, vatNumber, headers); if (response.getStatusCode() == HttpStatus.OK && response.hasBody()) { - log.info("Successfully checked vat number"); + logSuccess(); Map responseMap = response.getBody(); - processValidResponse(responseMap, vatCheckResponseBean); + if (responseMap != null) { + processValidResponseV1(responseMap, vatCheckResponseBean); + } else { + log.warn("Response map or vatCheckResponseBean is null."); + } } + } catch (FeignException ex) { if (ex.status() == 406) { try { Map errorResponse = Utils.parseErrorResponse(ex.contentUTF8()); - processValidResponse(errorResponse, vatCheckResponseBean); + processValidResponseV1(errorResponse, vatCheckResponseBean); } catch (Exception parseEx) { log.error("Failed to parse 406 error response: {0}", parseEx); } @@ -85,40 +93,144 @@ public class VatCheckDao { } return vatCheckResponseBean; } - public static void processValidResponse(Map responseMap, VatCheckResponseBean vatCheckResponseBean) { - if (responseMap != null && responseMap.containsKey("data")) { - Map responseBody = (Map) responseMap.get("data"); - if (responseBody != null) { - responseBody.remove("timestamp_creation"); - responseBody.remove("timestamp_last_update"); - responseBody.remove("data_iscrizione"); - responseBody.remove("id"); + public static void processValidResponseV1(Map responseMap, VatCheckResponseBean vatCheckResponseBean) { + Object dataObj = responseMap.get("data"); + if (dataObj instanceof Map rawDataMap) { + Map responseBody = new LinkedHashMap<>(); + rawDataMap.forEach((k, v) -> { + if (k instanceof String strKey) { + responseBody.put(strKey, v); + } + }); - Map data = new LinkedHashMap<>(); - data.put("data", responseBody); + List.of("timestamp_creation", "timestamp_last_update", "id", "data_iscrizione").forEach(responseBody.keySet()::remove); - vatCheckResponseBean.setValid(true); - vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); - vatCheckResponseBean.setVatCheckResponse(data); - } else { - vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); - } + Map data = new LinkedHashMap<>(); + data.put("data", responseBody); + + vatCheckResponseBean.setValid(true); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); + vatCheckResponseBean.setVatCheckResponse(data); } else { vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); } + } - public VatCheckResponseBean checkVatNumber(String vatNumber) { - try { - return checkVatNumberApi(vatNumber); - } catch (Exception e) { - log.error("Error in checkVatNumber: {}", e.getMessage()); + public VatCheckResponseBean checkVatNumber(String vatNumber) { + + try { + String vatApiVersion = getVatCheckVersion(); + if(!isVatCheckApiV2(vatApiVersion)){ + return checkVatNumberV1(vatNumber); + } + return checkVatNumberV2(vatNumber); + } catch (Exception e) { + logErrorMessage(e); + VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); + vatCheckResponseBean.setValid(false); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + return vatCheckResponseBean; + } + } + + public VatCheckResponseBean checkVatNumberV2(String vatNumber) { + VatCheckResponseBean vatCheckResponseBean = new VatCheckResponseBean(); vatCheckResponseBean.setValid(false); vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); - return vatCheckResponseBean; - } - } + if (Boolean.TRUE.equals(Boolean.parseBoolean(isVatCheckGloballyDisabled))) { + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + return vatCheckResponseBean; + } + try { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + headers.set(GepafinConstant.AUTHORIZATION, "Bearer " + vatCheckTokenV2); + URI baseUrl = URI.create(GepafinConstant.CHECK_VATNUMBER_URL_V2); + ResponseEntity> response = vatCheckV2Service.checkVatNumber(baseUrl, vatNumber, headers); + + if (response.getStatusCode() == HttpStatus.OK && response.hasBody()) { + logSuccess(); + Map responseMap = response.getBody(); + processValidResponse(responseMap, vatCheckResponseBean); + } + } catch (FeignException ex) { + if (ex.status() == 406) { + try { + Map errorResponse = Utils.parseErrorResponse(ex.contentUTF8()); + processValidResponse(errorResponse, vatCheckResponseBean); + } catch (Exception parseEx) { + log.error("Failed to parse 406 error response: {0}", parseEx); + } + } else { + log.error("Exception occurred while checking vat number: {0}", ex); + Utils.callException(ex.status(), ex); + } + } + return vatCheckResponseBean; + } + + public static void processValidResponse(Map responseMap, VatCheckResponseBean vatCheckResponseBean) { + + if (responseMap == null || !responseMap.containsKey("data")) { + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + return; + } + + Object dataObject = responseMap.get("data"); + if (!(dataObject instanceof List dataList) || dataList.isEmpty()) { + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + return; + } + + List> processedList = new ArrayList<>(); + + for (Object item : dataList) { + if (item instanceof Map mapItem) { + Map responseBody = new LinkedHashMap<>(); + mapItem.forEach((key, value) -> { + if (key instanceof String strKey) { + responseBody.put(strKey, value); + } + }); + + List.of("creationTimestamp", "lastUpdateTimestamp", "id").forEach(responseBody.keySet()::remove); + + processedList.add(responseBody); + } + } + + if (processedList.isEmpty()) { + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); + return; + } + + vatCheckResponseBean.setValid(true); + vatCheckResponseBean.setMessage(Translator.toLocale(GepafinConstant.VALID_VATNUMBER_MSG)); + vatCheckResponseBean.setVatCheckResponse(Map.of("data", processedList)); + } + + private void logSuccess() { + + log.info("Successfully checked vat number"); + } + + private static boolean isVatCheckApiV2(String vatApiVersion) { + boolean isNotBlank = StringUtils.isNotBlank(vatApiVersion); + boolean isNotEmpty = StringUtils.isNotEmpty(vatApiVersion); + return isNotBlank && isNotEmpty && Boolean.TRUE.equals(vatApiVersion.equals(VatCheckVersionTypeEnum.V2.getValue())); + } + + private String getVatCheckVersion() { + + return globalConfigRepository.findContentByTypeAndIsDeletedFalse(GepafinConstant.VAT_CHECK_API_VERSION); + } + + private void logErrorMessage(Exception e) { + + log.error("Error in checkVatNumber: {}", e.getMessage()); + } } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestView.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestView.java new file mode 100644 index 00000000..b5ee0ecc --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestView.java @@ -0,0 +1,67 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.Immutable; + +import java.time.LocalDateTime; + +@Entity +@Immutable +@Table(name = "application_amendment_request_view") +@Getter +@Setter +@IdClass(ApplicationAmendmentRequestViewId.class) +public class ApplicationAmendmentRequestView { + + + @Id + @Column(name = "ID") + private Long id; + + @Column(name = "APPLICATION_ID") + private Long applicationId; + + @Column(name = "PROTOCOL_NUMBER") + private Long protocolNumber; + + @Column(name = "CALL_NAME") + private String callName; + + @Column(name = "COMPANY_NAME") + private String companyName; + + @Column(name = "START_DATE") + private LocalDateTime startDate; + + @Column(name = "EXPIRATION_DATE") + private LocalDateTime expirationDate; + + @Column(name = "ASSIGNED_USER_NAME") + private String assigendUserName; + + @Column(name = "ASSIGNED_USER_ID") + private Long assignedUserId; + + @Column(name = "STATUS") + private String status; + + @Column(name = "NOTE") + private String note; + + @Column(name = "INTERNAL_NOTE") + private String internalNote; + + @Column(name = "APPLICATION_USER_ID") + private Long applicationUserId; + + @Column(name = "CREATED_DATE") + private String createdDate; + + @Column(name = "UPDATED_DATE") + private String updatedDate; + + @Column(name = "IS_DELETED") + private Boolean isDeleted; +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestViewId.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestViewId.java new file mode 100644 index 00000000..f80e5475 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestViewId.java @@ -0,0 +1,14 @@ +package net.gepafin.tendermanagement.entities; + +public class ApplicationAmendmentRequestViewId { + + private static final long serialVersionUID = 1L; + private Long id; + + public ApplicationAmendmentRequestViewId() { + } + + public ApplicationAmendmentRequestViewId(Long id) { + this.id = id; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationView.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationView.java new file mode 100644 index 00000000..54593c2e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationView.java @@ -0,0 +1,95 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.Immutable; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.LocalTime; + +@Entity +@Immutable +@Table(name = "application_view") +@Getter +@Setter +@IdClass(ApplicationViewId.class) +public class ApplicationView implements Serializable { + + @Id + @Column(name = "ID") + private Long id; + + @Column(name = "STATUS") + private String status; + + @Column(name = "IS_DELETED") + private Boolean isDeleted; + + @Column(name = "USER_ID") + private Long userId; + + @Column(name = "SUBMISSION_DATE") + private LocalDateTime submissionDate; + + @Column(name ="COMMENTS") + private String comments; + + @Column(name = "AMOUNT_REQUESTED") + private BigDecimal amountRequested; + + @Column(name = "AMOUNT_ACCEPTED") + private BigDecimal amountAccepted; + + @Column(name = "DATE_ACCEPTED") + private LocalDateTime dateAccepted; + + @Column(name = "DATE_REJECTED") + private LocalDateTime dateRejected; + + @Column(name = "EVALUATION_VERSION") + private String evaluationVersion; + + @Column(name = "CALL_ID") + private Long callId; + + @Column(name = "CALL_TITLE") + private String callTitle; + + @Column(name = "CALL_END_DATE") + private LocalDateTime callEndDate; + + @Column(name = "CALL_END_TIME") + private LocalTime callEndTime; + + @Column(name = "MODIFIED_DATE") + private LocalDateTime modifiedDate; + + @Column(name = "COMPANY_ID") + private Long companyId; + + @Column(name = "USER_WITH_COMPANY_ID") + private Long userWithCompanyId; + + @Column(name = "COMPANY_NAME") + private String companyName; + + @Column(name = "PROTOCOL_NUMBER") + private Long protocolNumber; + + @Column(name = "ASSIGNED_USER_ID") + private Long assignedUserId; + + @Column(name = "ASSIGNED_USER_NAME") + private String assignedUserName; + + @Column(name = "HUB_ID") + private Long hubId; + + @Column(name = "CREATED_DATE") + private LocalDateTime createdDate; + + +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationViewId.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationViewId.java new file mode 100644 index 00000000..f16ca359 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationViewId.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.entities; + +import lombok.Data; + +@Data +public class ApplicationViewId { + + private static final long serialVersionUID = 1L; + private Long id; + + public ApplicationViewId() { + } + + public ApplicationViewId(Long id) { + this.id = id; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsView.java b/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsView.java new file mode 100644 index 00000000..a446daff --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsView.java @@ -0,0 +1,61 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.*; +import lombok.Data; +import org.hibernate.annotations.Immutable; + +import java.time.LocalDateTime; + +@Entity +@Immutable +@Data +@Table(name = "assigned_applications_view") +@IdClass(AssignedApplicationsViewId.class) +public class AssignedApplicationsView{ + + @Id + @Column(name = "ID") + private Long id; + + @Column(name = "APPLICATION_ID") + private Long applicationId; + + @Column(name = "USER_ID") + private Long userId; + + @Column(name = "PROTOCOL_NUMBER") + private Long protocolNumber; + + @Column(name = "CALL_NAME") + private String callName; + + @Column(name = "COMPANY_NAME") + private String companyName; + + @Column(name = "STATUS") + private String status; + + @Column(name = "NDG") + private String ndg; + + @Column(name = "APPOINTMENT_ID") + private String appointmentId; + + @Column(name = "APPLICATION_STATUS") + private String applicationStatus; + + @Column(name = "SUBMISSION_DATE") + private LocalDateTime submissionDate; + + @Column(name = "EVALUATION_END_DATE") + private LocalDateTime evaluationEndDate; + + @Column(name = "CREATED_DATE") + private LocalDateTime createdDate; + + @Column(name = "UPDATED_DATE") + private LocalDateTime updatedDate; + + @Column(name = "IS_DELETED") + private Boolean isDeleted; +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsViewId.java b/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsViewId.java new file mode 100644 index 00000000..99c9609c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/AssignedApplicationsViewId.java @@ -0,0 +1,17 @@ +package net.gepafin.tendermanagement.entities; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class AssignedApplicationsViewId implements Serializable{ + private static final long serialVersionUID = 1L; + private Long id; + + public AssignedApplicationsViewId() {} + + public AssignedApplicationsViewId(Long id) { + this.id = id; + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/entities/GlobalConfigEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/GlobalConfigEntity.java new file mode 100644 index 00000000..3f55abdf --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/entities/GlobalConfigEntity.java @@ -0,0 +1,21 @@ +package net.gepafin.tendermanagement.entities; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Data; + +@Entity +@Data +@Table(name = "GLOBAL_CONFIG") +public class GlobalConfigEntity extends BaseEntity{ + + @Column(name = "CONTENT") + private String content; + + @Column(name = "TYPE") + private String type; + + @Column(name = "IS_DELETED") + private Boolean isDeleted = false; +} diff --git a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java index 05b42e3b..3746c7b1 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/DocOtherSourceTypeEnum.java @@ -8,7 +8,8 @@ public enum DocOtherSourceTypeEnum { DELETED_APPLICATION("DELETED_APPLICATION"), DELETED_EVALUATION("DELETED_EVALUATION"), DELETED_CALL("DELETED_CALL"), - DELETED_AMENDMENT("DELETED_AMENDMENT"); + DELETED_AMENDMENT("DELETED_AMENDMENT"), + DELETED_USER_SIGNED_DOCUMENT("DELETED_USER_SIGNED_DOCUMENT"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/EmailServiceTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/EmailServiceTypeEnum.java index 49c14743..7cf34d0e 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/EmailServiceTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/EmailServiceTypeEnum.java @@ -5,7 +5,8 @@ import com.fasterxml.jackson.annotation.JsonValue; public enum EmailServiceTypeEnum { MAILGUN_SERVICE("MAILGUN_SERVICE"), - PEC_SERVICE("PEC_SERVICE"); + PEC_SERVICE("PEC_SERVICE"), + SYSTEM_EMAIL_SERVICE("SYSTEM_EMAIL_SERVICE"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/VatCheckVersionTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/VatCheckVersionTypeEnum.java new file mode 100644 index 00000000..7d38f009 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/enums/VatCheckVersionTypeEnum.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum VatCheckVersionTypeEnum { + V1("V1"), + V2("V2"); + private String value; + + VatCheckVersionTypeEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentPaginationRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentPaginationRequestBean.java index 42318247..8f717f92 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentPaginationRequestBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/ApplicationAmendmentPaginationRequestBean.java @@ -4,6 +4,7 @@ import lombok.Data; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import java.util.List; +import java.util.Map; @Data public class ApplicationAmendmentPaginationRequestBean { @@ -11,4 +12,9 @@ public class ApplicationAmendmentPaginationRequestBean { private GlobalFilters globalFilters; private List status; + + private Map filters; + + private Boolean personalRecords; + } diff --git a/src/main/java/net/gepafin/tendermanagement/model/request/AssignedApplicationPageableRequestBean.java b/src/main/java/net/gepafin/tendermanagement/model/request/AssignedApplicationPageableRequestBean.java index 89b13bd4..afcf078f 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/request/AssignedApplicationPageableRequestBean.java +++ b/src/main/java/net/gepafin/tendermanagement/model/request/AssignedApplicationPageableRequestBean.java @@ -4,6 +4,7 @@ import lombok.Data; import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import java.util.List; +import java.util.Map; @Data public class AssignedApplicationPageableRequestBean { @@ -12,4 +13,7 @@ public class AssignedApplicationPageableRequestBean { private GlobalFilters globalFilters; private List status; + + private Map filters; + } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestViewResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestViewResponse.java new file mode 100644 index 00000000..e4139131 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestViewResponse.java @@ -0,0 +1,27 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class ApplicationAmendmentRequestViewResponse { + + private Long id; + + private Long applicationId; + + private Long protocolNumber; + + private String callName; + + private String companyName; + + private LocalDateTime startDate; + + private LocalDateTime expirationDate; + + private String assigendUserName; + + private String status; +} diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java new file mode 100644 index 00000000..94c2335a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationViewResponse.java @@ -0,0 +1,24 @@ +package net.gepafin.tendermanagement.model.response; + +import lombok.Data; +import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; +import net.gepafin.tendermanagement.model.BaseBean; + +import java.time.LocalDateTime; + +@Data +public class AssignedApplicationViewResponse extends BaseBean { + private Long userId; + private Long applicationId; + private AssignedApplicationEnum status; + private LocalDateTime submissionDate; + private ApplicationStatusTypeEnum applicationStatus; + private LocalDateTime evaluationEndDate; + private String ndg; + private String appointmentId; + private Long protocolNumber; + private String callName; + private String companyName; + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestViewRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestViewRepository.java new file mode 100644 index 00000000..adce7672 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestViewRepository.java @@ -0,0 +1,8 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestView; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface ApplicationAmendmentRequestViewRepository extends JpaRepository , JpaSpecificationExecutor { +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java index b4fdfcaf..b5cf7fb9 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationRepository.java @@ -177,4 +177,5 @@ public interface ApplicationRepository extends JpaRepository , JpaSpecificationExecutor { +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsViewRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsViewRepository.java new file mode 100644 index 00000000..231c7d88 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/AssignedApplicationsViewRepository.java @@ -0,0 +1,9 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.AssignedApplicationsView; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface AssignedApplicationsViewRepository extends JpaRepository , JpaSpecificationExecutor { + +} diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/GlobalConfigRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/GlobalConfigRepository.java new file mode 100644 index 00000000..1766884a --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/repositories/GlobalConfigRepository.java @@ -0,0 +1,11 @@ +package net.gepafin.tendermanagement.repositories; + +import net.gepafin.tendermanagement.entities.GlobalConfigEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +public interface GlobalConfigRepository extends JpaRepository { + + @Query("SELECT gc.content FROM GlobalConfigEntity gc WHERE gc.type = :vatCheckApiVersion AND gc.isDeleted = false") + String findContentByTypeAndIsDeletedFalse(String vatCheckApiVersion); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java b/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java index 7893b776..d54d49d3 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/ApplicationAmendmentRequestService.java @@ -9,6 +9,7 @@ import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestViewResponse; import net.gepafin.tendermanagement.model.response.PageableResponseBean; import net.gepafin.tendermanagement.model.response.GetAllAmendmentResponseBean; @@ -29,5 +30,5 @@ public interface ApplicationAmendmentRequestService { public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus(HttpServletRequest request, Long applicationAmendmentId, ApplicationAmendmentRequestEnum status); void sendReminderEmail(HttpServletRequest request,Long amendmentId); - PageableResponseBean> getApplicationAmendmentByPaginnation(HttpServletRequest request, Long userId, ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean); + PageableResponseBean> getApplicationAmendmentByPaginnation(HttpServletRequest request, Long userId, ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/AssignedApplicationsService.java b/src/main/java/net/gepafin/tendermanagement/service/AssignedApplicationsService.java index 6c03d8f4..85a4ec82 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/AssignedApplicationsService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/AssignedApplicationsService.java @@ -7,6 +7,7 @@ import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; +import net.gepafin.tendermanagement.model.response.AssignedApplicationViewResponse; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; import net.gepafin.tendermanagement.model.response.PageableResponseBean; @@ -23,6 +24,6 @@ public interface AssignedApplicationsService { AssignedApplicationsResponse updateAssignedApplication(HttpServletRequest request, Long id, UpdateAssignedApplicationRequest assignedApplicationsRequest); AssignedApplicationsResponse getAssignedApplicationById(HttpServletRequest request, Long id); AssignedApplicationsEntity validateAssignedApplication(Long assignedApplicationId); - PageableResponseBean> getAllAssignedApplicationsByPagination(HttpServletRequest request, Long userId, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean); + PageableResponseBean> getAllAssignedApplicationsByPagination(HttpServletRequest request, Long userId, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean); AssignedApplicationsResponse updateAssignedApplicationStatus(HttpServletRequest request, Long assignedApplicationId, AssignedApplicationEnum status); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java index ae752c04..74b6be0e 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/CompanyService.java @@ -2,7 +2,6 @@ package net.gepafin.tendermanagement.service; import java.io.ByteArrayOutputStream; import java.util.List; -import java.util.Map; import net.gepafin.tendermanagement.model.request.LimitRequest; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; diff --git a/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckService.java b/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckV1Service.java similarity index 71% rename from src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckService.java rename to src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckV1Service.java index 333ab3a1..015beb70 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckService.java +++ b/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckV1Service.java @@ -11,13 +11,9 @@ import org.springframework.web.bind.annotation.RequestHeader; import java.net.URI; import java.util.Map; -@FeignClient(value = "vat-check-service", url = GepafinConstant.CHECK_VATNUMBER_V2_NEW_URL) -public interface VatCheckService { - +@FeignClient(value = "vat-check-v1-service", url = GepafinConstant.CHECK_VATNUMBER_URL_V1) +public interface VatCheckV1Service { @GetMapping("/{vatNumber}") - ResponseEntity> checkVatNumber(URI baseUrl, - @PathVariable("vatNumber") String vatNumber, - @RequestHeader HttpHeaders headers - ); + ResponseEntity> checkVatNumber(URI baseUrl, @PathVariable("vatNumber") String vatNumber, @RequestHeader HttpHeaders headers); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckV2Service.java b/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckV2Service.java new file mode 100644 index 00000000..5dc07914 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/feignClient/VatCheckV2Service.java @@ -0,0 +1,19 @@ +package net.gepafin.tendermanagement.service.feignClient; + +import net.gepafin.tendermanagement.constants.GepafinConstant; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestHeader; + +import java.net.URI; +import java.util.Map; + +@FeignClient(value = "vat-check-v2-service", url = GepafinConstant.CHECK_VATNUMBER_URL_V2) +public interface VatCheckV2Service { + + @GetMapping("/{vatNumber}") + ResponseEntity> checkVatNumber(URI baseUrl, @PathVariable("vatNumber") String vatNumber, @RequestHeader HttpHeaders headers); +} diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java index af31f78a..1d7a38a9 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java @@ -13,12 +13,15 @@ import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequest; import net.gepafin.tendermanagement.model.request.ApplicationAmendmentRequestBean; import net.gepafin.tendermanagement.model.request.CloseAmendmentRequest; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestViewResponse; import net.gepafin.tendermanagement.model.response.PageableResponseBean; import net.gepafin.tendermanagement.model.response.GetAllAmendmentResponseBean; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.service.ApplicationAmendmentRequestService; +import net.gepafin.tendermanagement.service.UserService; 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; @@ -41,6 +44,9 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm @Autowired private ApplicationEvaluationRepository applicationEvaluationRepository; + @Autowired + private UserService userService; + @Override public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(HttpServletRequest request, Long applicationEvaluationId) { Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationEvaluationId); @@ -153,8 +159,16 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override - public PageableResponseBean> getApplicationAmendmentByPaginnation(HttpServletRequest request, Long userId, ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean) { - UserEntity user=validator.validateUser(request); - return applicationAmendmentRequestDao.getApplicationAmendmentByPaginnation(userId,amendmentPaginationRequestBean); + public PageableResponseBean> getApplicationAmendmentByPaginnation(HttpServletRequest request, Long userId, ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean) { + boolean isSpecialUser = validator.checkIsBeneficiary() || + validator.checkIsConfidi() || + validator.checkIsPreInstructor() || + validator.checkIsInstructorManager(); + + if (isSpecialUser && Boolean.TRUE.equals(validator.checkRequestedUserWithUserId(request,userId))) { + throw new CustomValidationException(Status.VALIDATION_ERROR, Translator.toLocale(GepafinConstant.INVALID_USER_ID)); + } + + return applicationAmendmentRequestDao.getApplicationAmendmentByPaginationByView(userId,amendmentPaginationRequestBean); } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java index ea3f22c2..879c72cf 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationServiceImpl.java @@ -1,6 +1,7 @@ package net.gepafin.tendermanagement.service.impl; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.dao.ApplicationDao; @@ -17,6 +18,7 @@ import net.gepafin.tendermanagement.model.request.ApplicationRequestBean; import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CallService; +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.ForbiddenAccessException; @@ -117,6 +119,7 @@ public class ApplicationServiceImpl implements ApplicationService { @Override @Transactional(rollbackFor = Exception.class) public ApplicationSignedDocumentResponse uploadSignedDocument(HttpServletRequest request, Long applicationId, MultipartFile file) { + Utils.validateFileType(file); return applicationDao.uploadSignedDocument(request, applicationId, file); } @@ -149,7 +152,7 @@ public class ApplicationServiceImpl implements ApplicationService { if (companyId != null) { validator.validateUserWithCompany(request, companyId); } - return applicationDao.getAllApplicationByPagination(userEntity,callId,companyId,applicationPageableRequestBean); + return applicationDao.getAllApplicationByPaginationByView(userEntity,callId,companyId,applicationPageableRequestBean); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/AssignedApplicationsServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/AssignedApplicationsServiceImpl.java index 48017b57..b6d67ed2 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/AssignedApplicationsServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/AssignedApplicationsServiceImpl.java @@ -9,6 +9,7 @@ import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; +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.service.AssignedApplicationsService; @@ -66,7 +67,7 @@ public class AssignedApplicationsServiceImpl implements AssignedApplicationsServ } @Override - public PageableResponseBean> getAllAssignedApplicationsByPagination(HttpServletRequest request, Long userId, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean) { + public PageableResponseBean> getAllAssignedApplicationsByPagination(HttpServletRequest request, Long userId, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean) { UserEntity user=validator.validateUser(request); return assignedApplicationsDao.getAllAssignedApplicationsByPagination(user,assignedApplicationPageableRequestBean,userId); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java index 74b680e4..c12e1ab3 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyDocumentServiceImpl.java @@ -9,6 +9,7 @@ import net.gepafin.tendermanagement.model.request.CompanyDocumentRequest; import net.gepafin.tendermanagement.model.response.CompanyDocumentResponseBean; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.service.CompanyDocumentService; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -31,6 +32,7 @@ public class CompanyDocumentServiceImpl implements CompanyDocumentService { public List uploadFileForCompany(HttpServletRequest request, List files, Long companyId, Long documentCategoryId , CompanyDocumentTypeEnum documentSourceTypeEnum, LocalDateTime expirationDate,String name) { Map userInfo = validator.getUserInfoFromToken(request); Long userId = validator.getUserId(userInfo); + files.forEach(Utils::validateFileType); return companyDocumentDao.uploadFileForCompany(request,userId,files,companyId,documentCategoryId,documentSourceTypeEnum,expirationDate,name); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java index 1e77eddb..924f379c 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/CompanyServiceImpl.java @@ -4,8 +4,10 @@ import java.io.ByteArrayOutputStream; import java.util.List; import java.util.Map; +import jdk.jshell.execution.Util; import net.gepafin.tendermanagement.model.request.LimitRequest; import net.gepafin.tendermanagement.model.response.VatCheckResponseBean; +import net.gepafin.tendermanagement.util.Utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -107,6 +109,7 @@ public class CompanyServiceImpl implements CompanyService { public CompanyDelegationResponse uploadCompanyDelegation(HttpServletRequest request, Long companyId, MultipartFile file) { UserEntity userEntity = validator.validateUser(request); validator.validateUserWithCompany(request, companyId); + Utils.validateFileType(file); return delegationDao.uploadCompanyDelegation(userEntity, companyId, file); } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java b/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java index d7a46aa6..087bf06b 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/DocumentServiceImpl.java @@ -11,6 +11,7 @@ import net.gepafin.tendermanagement.enums.DocumentSourceTypeEnum; import net.gepafin.tendermanagement.enums.DocumentTypeEnum; import net.gepafin.tendermanagement.model.response.DocumentResponseBean; import net.gepafin.tendermanagement.service.DocumentService; +import net.gepafin.tendermanagement.util.Utils; import net.gepafin.tendermanagement.util.Validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -31,6 +32,7 @@ public class DocumentServiceImpl implements DocumentService { public List uploadFile(HttpServletRequest request,List files, Long sourceId, DocumentSourceTypeEnum sourceType, DocumentTypeEnum fileType) { Map userInfo = validator.getUserInfoFromToken(request); Long userId = validator.getUserId(userInfo); + files.forEach(Utils::validateFileType); return documentDao.uploadFiles(userId,files,sourceId,sourceType,fileType); } @Override diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/EmailServiceFactory.java b/src/main/java/net/gepafin/tendermanagement/service/impl/EmailServiceFactory.java index 6ab6b270..fd8f757b 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/EmailServiceFactory.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/EmailServiceFactory.java @@ -12,13 +12,15 @@ public class EmailServiceFactory { @Autowired private MailgunEmailService mailgunEmailService; + @Autowired + private SystemEmailService systemEmailService; + public EmailService getEmailService(String serviceType) { - if ("MAILGUN_SERVICE".equals(serviceType)) { - return mailgunEmailService; - } else if ("PEC_SERVICE".equals(serviceType)) { - return pecEmailService; - } else { - throw new IllegalArgumentException("Invalid email service type: " + serviceType); - } + + return switch (serviceType) { + case "PEC_SERVICE" -> pecEmailService; + case "SYSTEM_EMAIL_SERVICE" -> systemEmailService; + default -> mailgunEmailService; + }; } } diff --git a/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java new file mode 100644 index 00000000..fde6fd3e --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/SystemEmailService.java @@ -0,0 +1,83 @@ +package net.gepafin.tendermanagement.service.impl; + +import com.mailgun.api.v3.MailgunMessagesApi; +import com.mailgun.client.MailgunClient; +import com.mailgun.model.message.MessageResponse; +import net.gepafin.tendermanagement.dao.EmailLogDao; +import net.gepafin.tendermanagement.entities.EmailLogEntity; +import net.gepafin.tendermanagement.enums.EmailServiceTypeEnum; +import net.gepafin.tendermanagement.enums.StatusTypeEnum; +import net.gepafin.tendermanagement.model.request.EmailConfig; +import net.gepafin.tendermanagement.model.request.EmailLogRequest; +import net.gepafin.tendermanagement.util.Utils; +import net.gepafin.tendermanagement.util.Validator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class SystemEmailService implements EmailService { + + @Value("${mailGun_user}") + public String mailGunUser; + + @Value("${mailGun_apiKey}") + public String mailGunApiKey; + + @Value("${mailGun_domainName}") + public String mailGunDomainName; + + @Value("${mailGun_base_url}") + public String mailGunBaseUrl; + + @Value("${isMailSendingEnabled}") + private String isEmailSendingEnabled; + + @Autowired + private Validator validator; + + @Autowired + private EmailLogDao emailLogDao; + + public final Logger log = LoggerFactory.getLogger(SystemEmailService.class); + + public void sendEmail(String subject, String body, List recipientEmails, EmailConfig emailConfig, EmailLogRequest emailLogRequest) { + + if (Boolean.FALSE.equals(Boolean.parseBoolean(isEmailSendingEnabled))) { + return; + } + + emailLogRequest.setEmailSubject(subject); + emailLogRequest.setEmailBody(body); + emailLogRequest.setSendStatus(StatusTypeEnum.SUCCESS.getValue()); + emailLogRequest.setRecipientEmails(Utils.listToCommaSeparatedString(recipientEmails)); + + if (Boolean.FALSE.equals(validator.isTestProfileActivated())) { + MessageResponse response = null; + try { + MailgunMessagesApi mailgunMessagesApi = MailgunClient.config(mailGunBaseUrl, mailGunApiKey).createApi(MailgunMessagesApi.class); + + String mailFrom = mailGunUser; + com.mailgun.model.message.Message message = com.mailgun.model.message.Message.builder().from(mailFrom).to(recipientEmails).subject(subject).html(body).build(); + + response = mailgunMessagesApi.sendMessage(mailGunDomainName, message); + } catch (Exception e) { + emailLogRequest.setSendStatus(StatusTypeEnum.FAILED.getValue()); + emailLogRequest.setEmailServiceType(EmailServiceTypeEnum.SYSTEM_EMAIL_SERVICE); + emailLogRequest.setErrorMessage(e.getMessage()); + emailLogDao.createEmailLog(emailLogRequest); + + throw new RuntimeException("Failed to send email via Mailgun: " + (response != null ? response.getMessage() : "No response from Mailgun"), e); + } + emailLogRequest.setEmailServiceResponse(response.toString()); + emailLogDao.createEmailLog(emailLogRequest); + } + } + +} + + diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 30ac3687..343e742a 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -5,9 +5,14 @@ import java.lang.reflect.Field; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.security.SecureRandom; +import java.sql.Timestamp; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; @@ -24,10 +29,17 @@ import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OneToOne; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Path; +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.enums.MatchModeEnum; +import net.gepafin.tendermanagement.model.request.FilterCriteria; import net.gepafin.tendermanagement.model.request.GlobalFilters; +import net.gepafin.tendermanagement.web.rest.api.errors.*; import net.objecthunter.exp4j.Expression; import net.objecthunter.exp4j.ExpressionBuilder; import org.apache.commons.collections4.MapUtils; @@ -45,13 +57,10 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import feign.FeignException; import io.micrometer.common.util.StringUtils; -import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientForbiddenException; -import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundException; -import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException; -import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.multipart.MultipartFile; import javax.crypto.Cipher; import javax.crypto.Mac; @@ -103,6 +112,7 @@ public class Utils { } return null; } + public static String extractFileName(String filePath) { if (filePath == null || filePath.isEmpty()) { return null; @@ -115,6 +125,7 @@ public class Utils { return filePath; } } + public static String decodeBase64String(String decodedString) { if (StringUtils.isBlank(decodedString)) { return decodedString; @@ -122,18 +133,20 @@ public class Utils { byte[] decode = Base64.getDecoder().decode(decodedString.getBytes(StandardCharsets.UTF_8)); return new String(decode, StandardCharsets.UTF_8); } - - public static void setIfNotNull(Consumer setter, T value) { - if (value != null) { - setter.accept(value); - } - } - public static void setIfUpdated(Supplier getter, Consumer setter, T newValue) { - T currentValue = getter.get(); - if (newValue != null && !newValue.equals(currentValue)) { - setter.accept(newValue); - } - } + + public static void setIfNotNull(Consumer setter, T value) { + if (value != null) { + setter.accept(value); + } + } + + public static void setIfUpdated(Supplier getter, Consumer setter, T newValue) { + T currentValue = getter.get(); + if (newValue != null && !newValue.equals(currentValue)) { + setter.accept(newValue); + } + } + public static String convertListToJsonString(List list) { try { return mapper.writeValueAsString(list); @@ -143,6 +156,7 @@ public class Utils { return null; } } + public static List convertJsonStringToList(String jsonString, Class clazz) { try { TypeReference> typeRef = new TypeReference>() { @@ -158,6 +172,7 @@ public class Utils { return null; } } + public static String convertMapIntoJsonString(Map map) { try { ObjectMapper mapper = new ObjectMapper(); @@ -172,6 +187,7 @@ public class Utils { } return null; } + public static Map convertIntoJson(String jsonString) { if (jsonString != null && !jsonString.isEmpty()) { try { @@ -184,6 +200,7 @@ public class Utils { } return null; } + public static U convertSourceObjectToDestinationObject(T source, Class destinationClass) { try { mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); @@ -194,6 +211,7 @@ public class Utils { } return null; } + public static void retainOnlySpecificFields(T requestObject, List retainFields) throws IllegalAccessException { // Get all declared fields of the request object's class Field[] fields = requestObject.getClass().getDeclaredFields(); @@ -209,22 +227,23 @@ public class Utils { } public static String encodeData(String data) { - return Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8)); - } + return Base64.getEncoder().encodeToString(data.getBytes(StandardCharsets.UTF_8)); + } - public static String decodeData(String token) { - byte[] decodedBytes = Base64.getDecoder().decode(token); - return new String(decodedBytes, StandardCharsets.UTF_8); - } + public static String decodeData(String token) { + byte[] decodedBytes = Base64.getDecoder().decode(token); + return new String(decodedBytes, StandardCharsets.UTF_8); + } public static String generateSecureSamlToken() { - SecureRandom secureRandom = new SecureRandom(); - byte[] tokenBytes = new byte[24]; - secureRandom.nextBytes(tokenBytes); - String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes); - log.debug("Generated secure token: {}", token); - return token; - } + SecureRandom secureRandom = new SecureRandom(); + byte[] tokenBytes = new byte[24]; + secureRandom.nextBytes(tokenBytes); + String token = Base64.getUrlEncoder().withoutPadding().encodeToString(tokenBytes); + log.debug("Generated secure token: {}", token); + return token; + } + public static String generateSecureToken() { SecureRandom secureRandom = new SecureRandom(); byte[] tokenBytes = new byte[5]; @@ -233,6 +252,7 @@ public class Utils { log.debug("Generated secure token: {}", token); return token; } + public static Map> convertStringIntoMap(String jsonString) { try { return mapper.readValue(jsonString, new TypeReference>>() { @@ -242,26 +262,26 @@ public class Utils { return null; } } - + public static void callException(Integer staus, FeignException ex) { switch (staus) { - case 400: - throw new FeignClientValidationException(HttpStatus.valueOf(staus), ex.getMessage()); + case 400: + throw new FeignClientValidationException(HttpStatus.valueOf(staus), ex.getMessage()); - case 401: - throw new FeignClientUnauthorizedException(HttpStatus.valueOf(staus), ex.getMessage()); + case 401: + throw new FeignClientUnauthorizedException(HttpStatus.valueOf(staus), ex.getMessage()); - case 403: - throw new FeignClientForbiddenException(HttpStatus.valueOf(staus), ex.getMessage()); + case 403: + throw new FeignClientForbiddenException(HttpStatus.valueOf(staus), ex.getMessage()); - case 404: - throw new FeignClientNotFoundException(HttpStatus.valueOf(staus), ex.getMessage()); - default: - log.error("Exception occured :- {0}", ex); - throw ex; + case 404: + throw new FeignClientNotFoundException(HttpStatus.valueOf(staus), ex.getMessage()); + default: + log.error("Exception occured :- {0}", ex); + throw ex; } } - + public static Boolean isValidEmail(String email) { String EMAIL_REGEX = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$"; if (email == null || email.isEmpty()) { @@ -275,7 +295,7 @@ public class Utils { String data = String.valueOf(System.currentTimeMillis()); return data.substring(data.length() - range); } - + public static String convertObjectToJsonString(Object object) { try { // Check if the object is a string @@ -319,7 +339,7 @@ public class Utils { } } - public static Map> parseJsonContent(String jsonContent) { + public static Map> parseJsonContent(String jsonContent) { ObjectMapper objectMapper = new ObjectMapper(); try { return mapper.readValue(jsonContent, HashMap.class); @@ -328,22 +348,23 @@ public class Utils { } return new HashMap<>(); } - + // Utility method to replace placeholders with their values, handling nulls public static String replacePlaceholders(String text, Map placeholders) { - if (text == null) { - return ""; - } - for (Map.Entry entry : placeholders.entrySet()) { - text = replaceNull(text, entry.getKey(), entry.getValue()); - } - return text; + if (text == null) { + return ""; + } + for (Map.Entry entry : placeholders.entrySet()) { + text = replaceNull(text, entry.getKey(), entry.getValue()); + } + return text; } // Method to safely replace nulls with an empty string or a default value private static String replaceNull(String text, String target, String replacement) { - return text.replace(target, replacement != null ? replacement : ""); + return text.replace(target, replacement != null ? replacement : ""); } + public static String getClientIpAddress(HttpServletRequest request) { String header = request.getHeader("X-Forwarded-For"); if (org.apache.commons.lang3.StringUtils.isBlank(header)) { @@ -352,6 +373,7 @@ public class Utils { return new StringTokenizer(header, ",").nextToken().trim(); } + public static List convertJsonToList(String json, TypeReference> typeRef) { ObjectMapper objectMapper = new ObjectMapper(); try { @@ -364,11 +386,15 @@ public class Utils { public static String convertObjectToJson(Object obj) { try { - if(obj == null){return null;} + if (obj == null) { + return null; + } return new ObjectMapper().writeValueAsString(obj); } catch (JsonProcessingException e) { log.error("Failed to convert object to JSON: {}", e.getMessage(), e); - throw new RuntimeException("Failed to convert object to JSON", e);}} + throw new RuntimeException("Failed to convert object to JSON", e); + } + } public static String replaceSpacesWithUnderscores(String content) { if (content == null) { @@ -376,10 +402,10 @@ public class Utils { } return content.trim().replace(" ", "_"); } + public static List> convertJsonStringIntoJsonList(String jsonString) { try { - if(isEmpty(jsonString)) - { + if (isEmpty(jsonString)) { return new ArrayList<>(); } ObjectMapper mapper = new ObjectMapper(); @@ -390,6 +416,7 @@ public class Utils { } return null; } + public static String convertToString(Object input) { if (input == null) { return "null"; // Return string "null" for null input @@ -451,6 +478,7 @@ public class Utils { throw new RuntimeException("Error converting map to string", e); } } + public static boolean isValidDateString(String dateStr) { Pattern datePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}"); return datePattern.matcher(dateStr).matches(); @@ -468,7 +496,7 @@ public class Utils { return targetFormat.format(date); } catch (ParseException e) { - log.error("error while prcoessing date formate"); + log.error("error while prcoessing date formate"); return null; } } @@ -514,6 +542,7 @@ public class Utils { return "Invalid amount format"; } } + public static boolean isItalianFormattedAmount(String input) { // Regular expression to match Italian-style amounts (e.g., 41.003,00 or 123,45) String sanitizedInput = input.replace(",", ""); @@ -526,7 +555,7 @@ public class Utils { public static String encryptCredential(String value) { try { - if(Boolean.FALSE.equals(isEmpty(value))) { + if (Boolean.FALSE.equals(isEmpty(value))) { IvParameterSpec iv = new IvParameterSpec(GepafinConstant.ENCRYPT_INIT_VECTOR.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(GepafinConstant.ENCRYPT_KEY), "AES"); @@ -547,7 +576,7 @@ public class Utils { public static String decryptCredential(String encrypted) { try { - if(Boolean.FALSE.equals(isEmpty(encrypted))) { + if (Boolean.FALSE.equals(isEmpty(encrypted))) { IvParameterSpec iv = new IvParameterSpec(GepafinConstant.ENCRYPT_INIT_VECTOR.getBytes("UTF-8")); SecretKeySpec skeySpec = new SecretKeySpec(Base64.getDecoder().decode(GepafinConstant.ENCRYPT_KEY), "AES"); @@ -610,19 +639,19 @@ public class Utils { return null; } } - - public static void setHttpServletRequestForScheduler() { - MockHttpServletRequest mockRequest = new MockHttpServletRequest(); - mockRequest.setRequestURI("/scheduled"); - mockRequest.setMethod("POST"); - ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest); - RequestContextHolder.setRequestAttributes(attributes); - } - public static void clearHttpServletRequest() { - // Clear the RequestContextHolder after task execution - RequestContextHolder.resetRequestAttributes(); - } + public static void setHttpServletRequestForScheduler() { + MockHttpServletRequest mockRequest = new MockHttpServletRequest(); + mockRequest.setRequestURI("/scheduled"); + mockRequest.setMethod("POST"); + ServletRequestAttributes attributes = new ServletRequestAttributes(mockRequest); + RequestContextHolder.setRequestAttributes(attributes); + } + + public static void clearHttpServletRequest() { + // Clear the RequestContextHolder after task execution + RequestContextHolder.resetRequestAttributes(); + } public static String generateAuthTokenForLoginToOdessa() { @@ -731,7 +760,8 @@ public class Utils { public static String createChannelForUserAndCompany(Long userId, Long companyId) { return GepafinConstant.COMMON_SINGLE_CHANNEL_PREFIX + userId + GepafinConstant.COMPANY_PREFIX + companyId; } - public static GlobalFilters setPageNumberAndLimit(GlobalFilters globalFilters){ + + public static GlobalFilters setPageNumberAndLimit(GlobalFilters globalFilters) { if (globalFilters == null) { if (globalFilters.getLimit() == null || globalFilters.getLimit() <= 0) { globalFilters.setLimit(GepafinConstant.DEFAULT_PAGE_LIMIT); @@ -759,6 +789,7 @@ public class Utils { private static Map defaultErrorResponse() { return Collections.singletonMap("message", Translator.toLocale(GepafinConstant.INVALID_VATNUMBER)); } + public static List extractValues(String input) { List extractedValues = new ArrayList<>(); Pattern pattern = Pattern.compile("\\{(.*?)\\}"); // Regex to match {value} @@ -769,6 +800,7 @@ public class Utils { } return extractedValues; } + public static double evaluateExpression(String expression) { try { Expression exp = new ExpressionBuilder(expression).build(); @@ -778,6 +810,7 @@ public class Utils { return Double.NaN; // Return NaN if the expression is invalid } } + public static boolean isNumeric(String input) { if (input == null || input.trim().isEmpty()) { return false; @@ -785,9 +818,11 @@ public class Utils { return input.matches("-?\\d+(\\.\\d+)?"); } + public static boolean isValidBoolean(String value) { return "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value); } + public static Map convertJsonStringToMap(String jsonString) { try { return mapper.readValue(jsonString, Map.class); @@ -796,6 +831,161 @@ public class Utils { return null; } } + + public static void applyStringFilter(Path fieldPath, CriteriaBuilder criteriaBuilder, List predicates, Object value, MatchModeEnum matchMode) { + if (value instanceof String) { + String valueStr = (String) value; + if (fieldPath.getJavaType().equals(String.class)) { + MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue()); + switch (mode) { + case CONTAINS -> + predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), "%" + valueStr.toLowerCase() + "%")); + case EQUALS -> predicates.add(criteriaBuilder.equal(fieldPath, valueStr)); + case STARTSWITH -> + predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), valueStr.toLowerCase() + "%")); + case ENDSWITH -> + predicates.add(criteriaBuilder.like(criteriaBuilder.lower(fieldPath.as(String.class)), "%" + valueStr.toLowerCase())); + } + } + } + } + + public static void applyNumberFilter(Path fieldPath, CriteriaBuilder criteriaBuilder, List predicates, Object value, MatchModeEnum matchMode) { + + if (Number.class.isAssignableFrom(fieldPath.getJavaType())) { + Number numberValue = null; + + if (value instanceof String stringValue) { + if (isInteger(stringValue)) { + numberValue = Long.parseLong(stringValue); + } else if (isDecimal(stringValue)) { + numberValue = Double.parseDouble(stringValue); + } + } else if (value instanceof Number number) { + numberValue = number; + } + if (numberValue != null) { + MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue()); + + if (mode == MatchModeEnum.EQUALS) { + predicates.add(criteriaBuilder.equal(fieldPath, numberValue)); + } + } + } + } + + private static boolean isInteger(String value) { + + try { + Long.parseLong(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + private static boolean isDecimal(String value) { + + try { + Double.parseDouble(value); + return value.contains("."); + } catch (NumberFormatException e) { + return false; + } + } + + public static void applyDateFilter(Path fieldPath, CriteriaBuilder criteriaBuilder, List predicates, Object value, MatchModeEnum matchMode, Root root) { + if (fieldPath.getJavaType().equals(LocalDateTime.class)) { + // Convert input string: Replace 'T' with space + String formattedValue = value.toString().replace("T", " "); + + // Handle timezones and UTC (`Z` or `+HH:mm`) + if (formattedValue.contains("Z") || formattedValue.matches(".*[+-]\\d{2}:\\d{2}$")) { + OffsetDateTime offsetDateTime = OffsetDateTime.parse(value.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME); + formattedValue = offsetDateTime.toLocalDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")); + } + + // Check if more than 3 decimal places exist + if (formattedValue.contains(".")) { + int dotIndex = formattedValue.indexOf("."); + if (formattedValue.length() > dotIndex + 4) { + formattedValue = formattedValue.substring(0, dotIndex + 4); // Keep only 3 decimals + } + } else { + formattedValue += ".000"; // Ensure 3 decimals + } + + // Define correct date-time format + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + + // Parse the formatted value into LocalDateTime + LocalDateTime dateTimeValue = LocalDateTime.parse(formattedValue, formatter); + + // Extract only the date portion + LocalDate dateValue = dateTimeValue.toLocalDate(); + + // Convert database field to LocalDate for date-only comparison + jakarta.persistence.criteria.Expression dateField = criteriaBuilder.function("DATE", LocalDate.class, fieldPath); + + MatchModeEnum mode = MatchModeEnum.fromObject(matchMode.getValue()); + + switch (mode) { + case DATEIS -> predicates.add(criteriaBuilder.equal(dateField, dateValue)); + case DATEISNOT -> predicates.add(criteriaBuilder.notEqual(dateField, dateValue)); + case BEFORE -> + predicates.add(criteriaBuilder.lessThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue))); + case AFTER -> + predicates.add(criteriaBuilder.greaterThan(fieldPath.as(Timestamp.class), Timestamp.valueOf(dateTimeValue))); + } + } + } + + + /** + * Extracts a Map from a parent Map safely. + */ + public static Map extractMap(Map parentMap, String key) { + Object obj = parentMap.get(key); + if (obj instanceof Map map) { + return (Map) map; + } + return null; + } + + /** + * Extracts a String from a Map safely. + */ + public static String extractString(Map parentMap, String key) { + Object obj = parentMap.get(key); + return (obj instanceof String str) ? str : null; + } + + public static void validateFileType(MultipartFile file) { + if (file.isEmpty()) { + throw new CustomValidationException(Status.VALIDATION_ERROR, + Translator.toLocale(GepafinConstant.VALIDATION_ERROR_FILE_EMPTY)); + } + } + + public static void applyFiltersByPagination(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 = root.get(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); + } + } + } + } + } public static List> convertJsonToListMap(String jsonString) { try { if (jsonString == null || jsonString.trim().isEmpty()) { @@ -820,4 +1010,6 @@ public class Utils { return Collections.emptyList(); } } + } + diff --git a/src/main/java/net/gepafin/tendermanagement/util/Validator.java b/src/main/java/net/gepafin/tendermanagement/util/Validator.java index 21e2bd1a..a68dc1bd 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Validator.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Validator.java @@ -206,4 +206,12 @@ public class Validator { } return false; } + public Boolean checkRequestedUserWithUserId(HttpServletRequest request,Long userId){ + UserEntity user=validateUser(request); + UserEntity requestedUser=userService.validateUser(userId); + if( Boolean.FALSE.equals(user.getId().equals(requestedUser.getId()))){ + return true; + } + return false; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java index 8f1c5b2b..eb0c05f0 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/ApplicationAmendmentRequestApi.java @@ -10,11 +10,7 @@ import jakarta.validation.Valid; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.model.request.*; -import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; -import net.gepafin.tendermanagement.model.response.ApplicationResponse; -import net.gepafin.tendermanagement.model.response.PageableResponseBean; -import net.gepafin.tendermanagement.model.response.SummaryPageResponseBean; -import net.gepafin.tendermanagement.model.response.GetAllAmendmentResponseBean; +import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.web.rest.api.errors.ErrorConstants; import org.springframework.http.MediaType; @@ -201,7 +197,7 @@ public interface ApplicationAmendmentRequestApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "/user/{userId}/pagination", produces = { "application/json" }) - ResponseEntity>>> getApplicationAmendmentByPaginnation(HttpServletRequest request, @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId, - @RequestBody ApplicationAmendmentPaginationRequestBean userActionPaginationRequest); + ResponseEntity>>> getApplicationAmendmentByPaginnation(HttpServletRequest request, @Parameter(description = "The user id", required = true) @PathVariable("userId") Long userId, + @RequestBody ApplicationAmendmentPaginationRequestBean userActionPaginationRequest); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java index caa2fa32..b3724765 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/AssignedApplicationsApi.java @@ -12,6 +12,7 @@ import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.response.ApplicationResponse; +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.Response; @@ -128,8 +129,8 @@ public interface AssignedApplicationsApi { @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON_VALUE, examples = { @ExampleObject(value = ErrorConstants.BADREQUEST_ERROR_EXAMPLE) })) }) @PostMapping(value = "/pagination", produces = "application/json") - ResponseEntity>>> getAllAssignedApplicationsByPagination(HttpServletRequest request, - @Parameter(description = "The User ID", required = false) @RequestParam(value = "userId",required = false) Long userId, @RequestBody AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean); + ResponseEntity>>> getAllAssignedApplicationsByPagination(HttpServletRequest request, + @Parameter(description = "The User ID", required = false) @RequestParam(value = "userId",required = false) Long userId, @RequestBody AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean); } diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java index 562a84b3..585a6d1e 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/ApplicationAmendmentRequestController.java @@ -9,6 +9,7 @@ import net.gepafin.tendermanagement.enums.UserActionContextEnum; import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.model.request.*; import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestResponse; +import net.gepafin.tendermanagement.model.response.ApplicationAmendmentRequestViewResponse; import net.gepafin.tendermanagement.model.response.PageableResponseBean; import net.gepafin.tendermanagement.model.response.GetAllAmendmentResponseBean; import net.gepafin.tendermanagement.model.util.Response; @@ -187,11 +188,11 @@ public class ApplicationAmendmentRequestController implements ApplicationAmendme } @Override - public ResponseEntity>>> getApplicationAmendmentByPaginnation(HttpServletRequest request, Long userId, ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean) { + public ResponseEntity>>> getApplicationAmendmentByPaginnation(HttpServletRequest request, Long userId, ApplicationAmendmentPaginationRequestBean amendmentPaginationRequestBean) { loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) .actionContext(UserActionContextEnum.GET_ALL_APPLICATION_AMENDMENT_BY_PAGINATION).build()); - PageableResponseBean> listPageableResponseBean=applicationAmendmentRequestService.getApplicationAmendmentByPaginnation(request,userId,amendmentPaginationRequestBean); + PageableResponseBean> listPageableResponseBean=applicationAmendmentRequestService.getApplicationAmendmentByPaginnation(request,userId,amendmentPaginationRequestBean); return ResponseEntity.status(HttpStatus.OK) .body(new Response<>(listPageableResponseBean, Status.SUCCESS, Translator.toLocale(GepafinConstant.APPLICATION_DATA_FOR_AMENDMENT_SUCCESS_MSG))); diff --git a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java index f6487d12..ec5becc7 100644 --- a/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java +++ b/src/main/java/net/gepafin/tendermanagement/web/rest/api/impl/AssignedApplicationsController.java @@ -12,10 +12,7 @@ import net.gepafin.tendermanagement.model.request.AssignedApplicationPageableReq import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.request.UpdateAssignedApplicationRequest; import net.gepafin.tendermanagement.model.request.UserActionRequest; -import net.gepafin.tendermanagement.model.response.ApplicationResponse; -import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; -import net.gepafin.tendermanagement.model.response.NotificationResponse; -import net.gepafin.tendermanagement.model.response.PageableResponseBean; +import net.gepafin.tendermanagement.model.response.*; import net.gepafin.tendermanagement.model.util.Response; import net.gepafin.tendermanagement.service.AssignedApplicationsService; import net.gepafin.tendermanagement.util.LoggingUtil; @@ -96,11 +93,11 @@ public class AssignedApplicationsController implements AssignedApplicationsApi { } @Override - public ResponseEntity>>> getAllAssignedApplicationsByPagination(HttpServletRequest request, Long userId, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean) { + public ResponseEntity>>> getAllAssignedApplicationsByPagination(HttpServletRequest request, Long userId, AssignedApplicationPageableRequestBean assignedApplicationPageableRequestBean) { loggingUtil.logUserAction(UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.VIEW) .actionContext(UserActionContextEnum.GET_ALL_ASSIGNED_APPLICATION_BY_PAGINATION).build()); - PageableResponseBean> assigenedApplicationResponses=assignedApplicationsService.getAllAssignedApplicationsByPagination(request, userId,assignedApplicationPageableRequestBean); + PageableResponseBean> assigenedApplicationResponses=assignedApplicationsService.getAllAssignedApplicationsByPagination(request, userId,assignedApplicationPageableRequestBean); return ResponseEntity.status(HttpStatus.OK).body(new Response<>(assigenedApplicationResponses, Status.SUCCESS, Translator.toLocale(GepafinConstant.GET_ASSIGNED_APPLICATION_SUCCESS_MSG))); } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 58295500..bc453374 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -14,7 +14,6 @@ isPecServiceEnabled = false #default_System_Receiver_Email=antonio.manca@bflows.net gepafin_email=rinaldo.bonazzo@bflows.net rinaldo_email=rinaldo.bonazzo@bflows.net -carlo_email=test@test.test default.hub.uuid=p4lk3bcx1RStqTaIVVbXs #Login to Odessa, Appointment Creation, Upload document Configuration diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index c49961d5..9cd21534 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -13,7 +13,6 @@ isPecServiceEnabled = false #default_System_Receiver_Email=test@test.test gepafin_email=test@test.test rinaldo_email=test@test.test -carlo_email=test@test.test default.hub.uuid=p4lk3bcx1RStqTaIVVbXs appointment.base.url=https://demo.galileonetwork.it/gateway/rest diff --git a/src/main/resources/application-production.properties b/src/main/resources/application-production.properties index cf3396fa..c4ad1fe9 100644 --- a/src/main/resources/application-production.properties +++ b/src/main/resources/application-production.properties @@ -20,7 +20,6 @@ isPecServiceEnabled = true #default_System_Receiver_Email=m.gaudino@gepafin.it,f.marinelli@gepafin.it gepafin_email=bandi@pec.gepafin.it rinaldo_email=rinaldo.bonazzo@bflows.net -carlo_email=carlo.mancosu@bflows.net default.hub.uuid=p4lk3bcx1RStqTaIVVbXs # TEST DEPLOY Configuration diff --git a/src/main/resources/application-testing.properties b/src/main/resources/application-testing.properties index 6fb983e5..532deb3f 100644 --- a/src/main/resources/application-testing.properties +++ b/src/main/resources/application-testing.properties @@ -11,7 +11,6 @@ isPecServiceEnabled = false #default_System_Receiver_Email=test@test.test gepafin_email=test@test.test rinaldo_email=test@test.test -carlo_email=test@test.test default.hub.uuid=p4lk3bcx1RStqTaIVVbXs appointment.base.url=https://demo.galileonetwork.it/gateway/rest diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3b9bd853..b165e997 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -47,7 +47,8 @@ fe.base.url=https://bandi-staging.memento.credit spring.main.allow-circular-references=true isVatCheckGloballyDisabled = true -vatCheckNewToken: 66026bd891a51044e90e08c4 +vatCheckTokenV1: 66026bd891a51044e90e08c4 +vatCheckTokenV2: 671916c76c6e822f660774d4 #SPID configuration spid.ipd.base.url=https://federatest.umbriadigitale.it @@ -55,7 +56,10 @@ active.profile.folder=dev # MailGun API mailGun_base_url=https://api.eu.mailgun.net/ - +#Below credentials are only for sending mail to rinaldo +mailGun_apiKey= 398e3dea1911fe941af261906ec99362-07e2c238-8094421f +mailGun_user=comunicazione@paghiamoci.ai +mailGun_domainName=paghiamoci.ai api.pecUrl=https://ws.pecmassiva.com #senderEmail=mailer@bflows.net diff --git a/src/main/resources/db/changelog/db.changelog-1.0.0.xml b/src/main/resources/db/changelog/db.changelog-1.0.0.xml index aa166039..38e13676 100644 --- a/src/main/resources/db/changelog/db.changelog-1.0.0.xml +++ b/src/main/resources/db/changelog/db.changelog-1.0.0.xml @@ -2684,6 +2684,59 @@ path="db/dump/create_application_form_view.sql"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/db/changelog/dynamic-triggers.xml b/src/main/resources/db/changelog/dynamic-triggers.xml index 9356279d..fbe5b5fe 100644 --- a/src/main/resources/db/changelog/dynamic-triggers.xml +++ b/src/main/resources/db/changelog/dynamic-triggers.xml @@ -13,10 +13,13 @@ BEGIN -- Loop through all tables in the schema that have the 'updated_date' column FOR r IN ( - SELECT table_name - FROM information_schema.columns - WHERE column_name = 'updated_date' - AND table_schema = 'gepafin_schema' + SELECT c.table_name + FROM information_schema.columns c + JOIN information_schema.tables t + ON c.table_name = t.table_name AND c.table_schema = t.table_schema + WHERE c.column_name = 'updated_date' + AND c.table_schema = 'gepafin_schema' + AND t.table_type = 'BASE TABLE' -- Excludes views ) LOOP EXECUTE format( @@ -30,10 +33,13 @@ -- Loop through all tables in the schema that have the 'created_date' column FOR r IN ( - SELECT table_name - FROM information_schema.columns - WHERE column_name = 'created_date' - AND table_schema = 'gepafin_schema' + SELECT c.table_name + FROM information_schema.columns c + JOIN information_schema.tables t + ON c.table_name = t.table_name AND c.table_schema = t.table_schema + WHERE c.column_name = 'created_date' + AND c.table_schema = 'gepafin_schema' + AND t.table_type = 'BASE TABLE' -- Excludes views ) LOOP EXECUTE format( diff --git a/src/main/resources/db/dump/create_application_amendment_request_view.sql b/src/main/resources/db/dump/create_application_amendment_request_view.sql new file mode 100644 index 00000000..ec882e6e --- /dev/null +++ b/src/main/resources/db/dump/create_application_amendment_request_view.sql @@ -0,0 +1,26 @@ +CREATE OR REPLACE VIEW application_amendment_request_view AS + +SELECT a.id, + a.application_id, + p.protocol_number, + cl.name AS call_name, + c.company_name, + a.start_date, + a.end_date AS expiration_date, + COALESCE(NULLIF(TRIM(BOTH FROM concat(COALESCE(u.first_name, ''), ' ', COALESCE(u.last_name, ''))), ''), '') AS assigned_user_name, + aa.user_id AS assigned_user_id, + a.status, + a.note, + a.internal_note, + app.user_id AS application_user_id, + a.created_date, + a.updated_date, + a.is_deleted +FROM gepafin_schema.application_amendment_request a +LEFT JOIN gepafin_schema.application app ON a.application_id = app.id AND (app.is_deleted IS FALSE OR app.is_deleted IS NULL) +LEFT JOIN gepafin_schema.call cl ON app.call_id = cl.id +LEFT JOIN gepafin_schema.company c ON app.company_id = c.id +LEFT JOIN gepafin_schema.protocol p ON a.protocol_id = p.id +LEFT JOIN gepafin_schema.assigned_applications aa ON app.id = aa.application_id AND (aa.is_deleted IS FALSE OR aa.is_deleted IS NULL) +LEFT JOIN gepafin_schema.gepafin_user u ON aa.user_id = u.id +WHERE a.is_deleted IS FALSE OR a.is_deleted IS NULL ORDER BY id; \ No newline at end of file diff --git a/src/main/resources/db/dump/create_application_view.sql b/src/main/resources/db/dump/create_application_view.sql new file mode 100644 index 00000000..e232f895 --- /dev/null +++ b/src/main/resources/db/dump/create_application_view.sql @@ -0,0 +1,81 @@ +CREATE OR REPLACE VIEW application_view AS + +SELECT + a.id, + a.status, + a.submission_date, + a.comments, + a.amount_requested, + a.amount_accepted, + a.date_accepted, + a.date_rejected, + a.is_deleted, + a.hub_id, + a.user_id, + a.evaluation_version AS evaluation_version, + a.updated_date AS modified_date, + a.created_date AS created_date, + + + + -- Call Details + a.call_id AS call_id, + cl.name AS call_title, + cl.end_date AS call_end_date, + cl.end_time AS call_end_time, + + -- Company Details + a.COMPANY_ID AS company_id, + c.company_name AS company_name, + + -- Protocol Details + p.protocol_number AS protocol_number, + + + -- Assigned User Details from ASSIGNED_APPLICATION and GEPPAFIN_USER + COALESCE(aa.user_id, NULL) AS assigned_user_id, + COALESCE( + NULLIF( + TRIM(CONCAT( + COALESCE(u.first_name, ''), ' ', + COALESCE(u.last_name, '') + )), + '' + ), + '' + ) AS assigned_user_name, + +-- User with Company Details (From Application's User) + COALESCE(uwc.id, NULL) AS user_with_company_id + + +FROM gepafin_schema.APPLICATION a + +-- Join Call Entity +LEFT JOIN gepafin_schema.CALL cl + ON a.CALL_ID = cl.id + +-- Join Company Entity (Ensuring it is not deleted) +LEFT JOIN gepafin_schema.COMPANY c + ON a.COMPANY_ID = c.id + +-- Join Protocol Entity +LEFT JOIN gepafin_schema.PROTOCOL p + ON a.PROTOCOL_NUMBER = p.id + +-- Join Assigned Application Entity (Ensuring it is not deleted) +LEFT JOIN gepafin_schema.assigned_applications aa + ON a.id = aa.APPLICATION_ID + AND (aa.IS_DELETED IS FALSE OR aa.IS_DELETED IS NULL) + + -- Join User Entity (Get First & Last Name Combined) +LEFT JOIN gepafin_schema.GEPAFIN_USER u + ON aa.user_id = u.id + + -- Get User With Company ID (From Application's User & Company) + LEFT JOIN gepafin_schema.USER_WITH_COMPANY uwc + ON a.user_id = uwc.user_id + AND a.COMPANY_ID = uwc.company_id + AND uwc.is_deleted = FALSE -- Ensuring the user is active + +WHERE a.IS_DELETED IS FALSE OR a.IS_DELETED IS NULL; \ No newline at end of file diff --git a/src/main/resources/db/dump/create_assigned_application_view.sql b/src/main/resources/db/dump/create_assigned_application_view.sql new file mode 100644 index 00000000..f1900b37 --- /dev/null +++ b/src/main/resources/db/dump/create_assigned_application_view.sql @@ -0,0 +1,52 @@ +CREATE OR REPLACE VIEW assigned_applications_view AS +SELECT + -- From assigned_applications + aa.id AS id, + aa.user_id AS user_id, + aa.status AS status, + aa.created_date AS created_date, + aa.updated_date AS updated_date, + aa.is_deleted AS is_deleted, + + -- From application + a.id AS application_id, + a.status AS application_status, + a.submission_date AS submission_date, + ae.end_date AS evaluation_end_date, + a.ndg AS ndg, + a.appointment_id AS appointment_id, + + -- From protocol (OneToOne) + p.protocol_number AS protocol_number, + + -- From call (ManyToOne) + cl.name AS call_name, + + -- From company (ManyToOne) + c.company_name AS company_name + +FROM gepafin_schema.assigned_applications aa + +-- Join application (ManyToOne from assigned_applications) +LEFT JOIN gepafin_schema.application a + ON aa.application_id = a.id + AND (a.is_deleted IS FALSE OR a.is_deleted IS NULL) + +-- Join application_evaluation (application_id matches + not deleted) +LEFT JOIN gepafin_schema.application_evaluation ae + ON ae.application_id = a.id + AND (ae.is_deleted IS FALSE OR ae.is_deleted IS NULL) + +-- Join protocol (OneToOne from application) +LEFT JOIN gepafin_schema.protocol p + ON a.protocol_number = p.id + +-- Join call (ManyToOne from application) +LEFT JOIN gepafin_schema.call cl + ON a.call_id = cl.id + +-- Join company (ManyToOne from application) +LEFT JOIN gepafin_schema.company c + ON a.company_id = c.id + +WHERE aa.is_deleted IS FALSE OR aa.is_deleted IS NULL; diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 2c27f379..e67042ab 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -60,7 +60,8 @@ status.same.error=Status is already set. invalid.status.change.from.draft=Status cannot be changed to READY_TO_PUBLISH or PUBLISH from DRAFT. status.cannot.be.changed=Status cannot be changed. published.call.not.update=Published call cannot be updated. -invalid.status.change.from.publish=Status cannot be changed to READY_TO_PUBLISH or DRAFT from PUBLISH. +invalid.status.change.from.publish=Status cannot be changed to READY_TO_PUBLISH from PUBLISH. +invalid.status.change.from.publish.to.draft=Status cannot be changed to DRAFT from PUBLISH as Applications are already created for this CALL. validation.table.message=Data for field {0} is not present. @@ -398,3 +399,4 @@ error.invalid.limit=Limit should be between 1 and 3000. insufficient.score.msg = Insufficient score to pass to the technical and economic-financial evaluation password.expired.for.login.to.odessa = Odessa login password has been expired. +invalid.user=Invalid user. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index 7a77bd5e..fd7f09e1 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -60,8 +60,8 @@ status.same.error=Lo stato ? gi? impostato. invalid.status.change.from.draft=Lo stato non pu? essere cambiato in READY_TO_PUBLISH o PUBLISH da DRAFT. status.cannot.be.changed=Lo stato non pu? essere cambiato. published.call.not.update=Il bando pubblicato non pu? essere aggiornato. -invalid.status.change.from.publish=Lo stato non pu? essere modificato in READY_TO_PUBLISH o DRAFT da PUBLISH. - +invalid.status.change.from.publish=Lo stato non pu? essere modificato in READY_TO_PUBLISH da PUBLISH. +invalid.status.change.from.publish.to.draft=Lo stato non pu essere modificato da PUBLISH a DRAFT poich sono gi state create applicazioni per questa CALL. # Login-related messages login.successfully=Accesso effettuato con successo. @@ -389,4 +389,5 @@ error.invalid.limit=Il limite dovrebbe essere compreso tra 1 e 3000. insufficient.score.msg = Punteggio non sufficiente per passaggio alla valutazione tecnica ed economico finanziaria validation.table.message=I dati per il campo {0} non sono presenti. -password.expired.for.login.to.odessa = La password di accesso a Odessa è scaduta \ No newline at end of file +password.expired.for.login.to.odessa = La password di accesso a Odessa è scaduta +invalid.user=Utente non valido. \ No newline at end of file