From 36725d3d46263b02c1ef4007dbbf441b94653d45 Mon Sep 17 00:00:00 2001 From: nisha Date: Sun, 24 Nov 2024 23:52:51 +0530 Subject: [PATCH 1/4] Done ticket GEPAFINBE-90 --- .../constants/GepafinConstant.java | 2 + .../dao/ApplicationAmendmentRequestDao.java | 58 +++++++++++++++++-- .../dao/ApplicationEvaluationDao.java | 19 ++++-- .../ApplicationAmendmentRequestEntity.java | 3 + .../entities/ApplicationEvaluationEntity.java | 21 ++++++- .../ApplicationEvaluationStatusTypeEnum.java | 1 + .../ApplicationAmendmentRequestResponse.java | 1 + .../ApplicationEvaluationResponse.java | 2 +- ...ApplicationAmendmentRequestRepository.java | 17 ++++++ .../ApplicationEvaluationRepository.java | 4 +- .../ApplicationEvaluationScheduler.java | 29 ++++++++++ .../scheduler/NotificationScheduler.java | 31 +++++++--- .../db/changelog/db.changelog-1.0.0.xml | 16 +++++ src/main/resources/message_en.properties | 3 + src/main/resources/message_it.properties | 2 + 15 files changed, 186 insertions(+), 23 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java diff --git a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java index 272d3f23..9d477c37 100644 --- a/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java +++ b/src/main/java/net/gepafin/tendermanagement/constants/GepafinConstant.java @@ -294,5 +294,7 @@ public class GepafinConstant { public static final String DUPLICATE_BENEFICIARY_CALL = "beneficiary.call.duplicate"; public static final String COMPANY_ID_REQUIRED_FOR_PREFERRED_CALL = "company.id.required.for.preferred.call"; public static final String CREATED_DATE = "createdDate"; + public static final String RESPONSE_DAYS_NOT_NULL="response.days.not.null"; + public static final String APPLICATION_CANNOT_APPROVED_OR_REJECTED="application.cannot.approved.or.rejected"; } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index a4da3b00..c646c73b 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -31,6 +31,7 @@ import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; +import static java.time.temporal.ChronoUnit.DAYS; import static net.gepafin.tendermanagement.util.Utils.log; import static net.gepafin.tendermanagement.util.Utils.setIfUpdated; @@ -97,6 +98,9 @@ public class ApplicationAmendmentRequestDao { @Autowired private EmailLogDao emailLogDao; + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + public ApplicationAmendmentRequestResponse getApplicationDataForAmendment(Long applicationEvaluationId) { log.info("Fetching the application data for the Amendment process {}", applicationEvaluationId); ApplicationEvaluationEntity applicationEvaluationEntity = applicationEvaluationService.validateApplicationEvaluation(applicationEvaluationId); @@ -204,6 +208,11 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); + if(applicationAmendmentRequest.getResponseDays()==null && applicationAmendmentRequest.getResponseDays() < 0){ + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.RESPONSE_DAYS_NOT_NULL)); + } + applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequest.getResponseDays())); + applicationAmendmentRequestEntity.setIsEmail(applicationAmendmentRequest.getIsSendEmail()); applicationAmendmentRequestEntity.setIsNotification(applicationAmendmentRequest.getIsSendNotification()); applicationAmendmentRequestEntity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); @@ -228,6 +237,20 @@ public class ApplicationAmendmentRequestDao { String formFieldsJson = Utils.convertObjectToJson(formFieldRequestBean); applicationAmendmentRequestEntity.setFormFields(formFieldsJson); } + List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(applicationEvaluationEntity.getId()); + // Ensure startDate and initialDays are not null to avoid NullPointerException + if (amendmentRequest !=null && amendmentRequest.isEmpty() && applicationEvaluationEntity.getStartDate() != null && applicationEvaluationEntity.getInitialDays() != null ) { + Long initialDays = applicationEvaluationEntity.getInitialDays(); + LocalDateTime startDate = applicationEvaluationEntity.getStartDate(); + LocalDateTime nowInUTC = DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + // Calculate remaining days + Long remainingDays = initialDays - DAYS.between(startDate, nowInUTC); + // Set remaining days in the entity + applicationEvaluationEntity.setRemainingDays(remainingDays); + //Set stop date time in the entity becuase amendment has started + applicationEvaluationEntity.setStopDateTime(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + } + UserEntity userEntity = userService.validateUser(applicationEvaluationEntity.getUserId()); Long protocolNumber = protocolDao.getProtocolNumber(userEntity.getHub()); ProtocolEntity protocolEntity = protocolDao.createProtocolEntity( @@ -238,6 +261,7 @@ public class ApplicationAmendmentRequestDao { //Set Status applicationEvaluationEntity.setStatus(ApplicationEvaluationStatusTypeEnum.SOCCORSO.getValue()); + applicationEvaluationRepository.save(applicationEvaluationEntity); ApplicationEntity applicationEntity = applicationService.validateApplication(applicationId); @@ -271,10 +295,8 @@ public class ApplicationAmendmentRequestDao { applicationAmendmentRequestResponse.setInternalNote(applicationAmendmentRequestEntity.getInternalNote()); LocalDateTime startDate = applicationAmendmentRequestEntity.getStartDate(); applicationAmendmentRequestResponse.setStartDate(startDate); - - LocalDateTime expirationDate = startDate.plus(expirationDays, ChronoUnit.DAYS); - applicationAmendmentRequestResponse.setExpirationDate(expirationDate); - + applicationAmendmentRequestResponse.setExpirationDate(applicationAmendmentRequestEntity.getEndDate()); + applicationAmendmentRequestResponse.setEvaluationEndDate(applicationAmendmentRequestEntity.getApplicationEvaluationEntity().getEndDate()); applicationAmendmentRequestResponse.setIsSendEmail(applicationAmendmentRequestEntity.getIsEmail()); applicationAmendmentRequestResponse.setIsSendNotification(applicationAmendmentRequestEntity.getIsNotification()); String callName = application.getCall().getName(); @@ -642,6 +664,19 @@ public class ApplicationAmendmentRequestDao { log.info("Closing application amendement with ID: {}", id); ApplicationAmendmentRequestEntity existingApplicationAmendment = validateApplicationAmendmentRequest(id); + List amendmentRequestList = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse( + existingApplicationAmendment.getApplicationEvaluationEntity().getId() + ); + + // Check if this is the last amendment being closed + boolean isLastRemaining = amendmentRequestList.stream() + .filter(amendment -> !amendment.getId().equals(id)) // Exclude the current amendment + .allMatch(amendment -> amendment.getStatus().equals(ApplicationAmendmentRequestEnum.CLOSE.getValue())); + + if (isLastRemaining) { + log.info("The current amendment is the last remaining one to be closed."); + applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(existingApplicationAmendment.getApplicationEvaluationEntity()); + } setIfUpdated(existingApplicationAmendment::getInternalNote, existingApplicationAmendment::setInternalNote, closeAmendmentRequest.getInternalNote()); setIfUpdated(existingApplicationAmendment::getStatus, existingApplicationAmendment::setStatus, ApplicationAmendmentRequestEnum.CLOSE.getValue()); @@ -669,6 +704,7 @@ public class ApplicationAmendmentRequestDao { if (newResponseDays != null && newResponseDays > 0) { Long currentResponseDays = request.getResponseDays() != null ? request.getResponseDays() : 0L; request.setResponseDays(currentResponseDays + newResponseDays); + request.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(request.getResponseDays()))); applicationAmendmentRequestRepository.save(request); } return convertEntityToResponse(request); @@ -762,12 +798,24 @@ public class ApplicationAmendmentRequestDao { LocalDateTime dueDate = amendment.getStartDate().plusDays(amendment.getResponseDays()); bodyPlaceholders.put("{{amendment_due_date}}", DateTimeUtil.formatLocalDateTime(dueDate, GepafinConstant.DD_MM_YYYY)); } else { - bodyPlaceholders.put("{{amendment_due_date}}", "Not available"); } return Utils.replacePlaceholders(template.getHtmlContent(), bodyPlaceholders); } + public ApplicationEvaluationEntity calculateEndDateAndSuspensionDays(ApplicationEvaluationEntity applicationEvaluationEntity){ + LocalDateTime currentDate=DateTimeUtil.DateServerToUTC(LocalDateTime.now()); + LocalDateTime endDate=currentDate.plusDays(applicationEvaluationEntity.getRemainingDays()); + Long suspendedDays = ChronoUnit.DAYS.between(applicationEvaluationEntity.getStopDateTime(), currentDate); + applicationEvaluationEntity.setEndDate(endDate); + applicationEvaluationEntity.setSuspendedDays(applicationEvaluationEntity.getSuspendedDays()+suspendedDays); + return applicationEvaluationRepository.save(applicationEvaluationEntity); + } + public List getApplicationAmendmentRequestEntitiesByApplicationEvaluationId(Long applicationEvaluationId){ + List applicationAmendmentRequestEntities=new ArrayList<>(); + applicationAmendmentRequestEntities=applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(applicationEvaluationId,ApplicationAmendmentRequestEnum.CLOSE.getValue()); + return applicationAmendmentRequestEntities; + } } diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java index 2bcbade9..e9bd2098 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationEvaluationDao.java @@ -17,7 +17,9 @@ import net.gepafin.tendermanagement.repositories.*; import net.gepafin.tendermanagement.service.ApplicationService; import net.gepafin.tendermanagement.service.CallService; import net.gepafin.tendermanagement.service.UserService; +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.ResourceNotFoundException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; @@ -96,6 +98,11 @@ public class ApplicationEvaluationDao { entity.setFile(Utils.convertObjectToJson(req.getFiles())); entity.setNote(req.getNote()); entity.setIsDeleted(false); + entity.setInitialDays(30L); + entity.setRemainingDays(30L); + entity.setSuspendedDays(0L); + entity.setStartDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + entity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(30))); entity.setStatus(ApplicationEvaluationStatusTypeEnum.OPEN.getValue()); return entity; } @@ -127,6 +134,7 @@ public class ApplicationEvaluationDao { response.setAssignedApplicationId(assignedApplications.getId()); response.setNote(entity.getNote()); response.setStatus(ApplicationEvaluationStatusTypeEnum.valueOf(entity.getStatus())); + response.setEvaluationEndDate(entity.getEndDate()); response.setCreatedDate(entity.getCreatedDate()); response.setUpdatedDate(entity.getUpdatedDate()); } @@ -405,7 +413,6 @@ public class ApplicationEvaluationDao { response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null); response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null); response.setSubmissionDate(application.getSubmissionDate() != null ? application.getSubmissionDate() : null); - response.setEvaluationDate(application.getSubmissionDate() != null ? application.getSubmissionDate().plusDays(30) : null); LocalDateTime callEndDate = application.getCall().getEndDate(); response.setCallEndDate(callEndDate); } @@ -631,6 +638,7 @@ public class ApplicationEvaluationDao { response.setApplicationStatus(ApplicationStatusTypeEnum.valueOf(application.getStatus())); response.setStatus(ApplicationEvaluationStatusTypeEnum.valueOf(ApplicationEvaluationStatusTypeEnum.OPEN.getValue())); response.setMinScore(call.getThreshold()!=null?call.getThreshold():null); + response.setEvaluationEndDate(entity.getEndDate()); LocalDateTime callEndDate = application.getCall().getEndDate(); response.setCallEndDate(callEndDate); setCriteriaResponses(entity, application.getId(), response, evaluationCriterias); @@ -928,7 +936,6 @@ public class ApplicationEvaluationDao { response.setCallName(application.getCall().getName() != null ? application.getCall().getName() : null); response.setProtocolNumber(application.getProtocol() != null ? application.getProtocol().getProtocolNumber() : null); response.setSubmissionDate(application.getSubmissionDate() != null ? application.getSubmissionDate() : null); - response.setEvaluationDate(application.getSubmissionDate() != null ? application.getSubmissionDate().plusDays(30) : null); } private Optional findFormFieldValue(Long applicationId, String formFieldId) { @@ -1307,10 +1314,10 @@ public class ApplicationEvaluationDao { entity = applicationEvaluationRepository.save(existingEntity); assignedApplicationsRepository.save(assignedApplicationsEntity); - List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndIsDeletedFalse(entity.getId()); - for (ApplicationAmendmentRequestEntity request : amendmentRequest) { - request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); - } + List amendmentRequest = applicationAmendmentRequestRepository.findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(existingEntity.getId(),ApplicationAmendmentRequestEnum.AWAITING.getValue()); + if(amendmentRequest !=null && Boolean.FALSE.equals(amendmentRequest.isEmpty())){ + throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.APPLICATION_CANNOT_APPROVED_OR_REJECTED)); + } applicationAmendmentRequestRepository.saveAll(amendmentRequest); if (Boolean.TRUE.equals(statusType.equals((ApplicationStatusTypeEnum.APPROVED.getValue())))) { emailNotificationDao.sendAdmissibilityNotificationEmailForApprovedApplication(application); diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java index 4d2dabf6..4b3fe79c 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationAmendmentRequestEntity.java @@ -47,4 +47,7 @@ public class ApplicationAmendmentRequestEntity extends BaseEntity { @JoinColumn(name = "PROTOCOL_Id") private ProtocolEntity protocol; + @Column(name = "end_date") + private LocalDateTime endDate; + } diff --git a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java index dae9a3fb..8f6eb656 100644 --- a/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java +++ b/src/main/java/net/gepafin/tendermanagement/entities/ApplicationEvaluationEntity.java @@ -3,6 +3,8 @@ package net.gepafin.tendermanagement.entities; import jakarta.persistence.*; import lombok.Data; +import java.time.LocalDateTime; + @Data @Entity @Table(name = "application_evaluation") @@ -35,5 +37,22 @@ public class ApplicationEvaluationEntity extends BaseEntity{ @ManyToOne @JoinColumn(name = "assigned_applications_id", nullable = true) private AssignedApplicationsEntity assignedApplicationsEntity; - + + @Column(name = "INITIAL_DAYS") + private Long initialDays; + + @Column(name = "REMAINING_DAYS") + private Long remainingDays; + + @Column(name = "SUSPENDED_DAYS") + private Long suspendedDays; + + @Column(name = "START_DATE") + private LocalDateTime startDate; + + @Column(name = "END_DATE") + private LocalDateTime endDate; + + @Column(name = "STOP_DATE_TIME") + private LocalDateTime stopDateTime; } diff --git a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java index 18cfc30d..59e47f9a 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/ApplicationEvaluationStatusTypeEnum.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonValue; public enum ApplicationEvaluationStatusTypeEnum { OPEN ("OPEN"), SOCCORSO("SOCCORSO"), + EXPIRED("EXPIRED"), CLOSE("CLOSE"); private String value; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java index 76e445de..5523098e 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationAmendmentRequestResponse.java @@ -23,6 +23,7 @@ public class ApplicationAmendmentRequestResponse { private List applicationFormFields; private Long applicationId; private Long applicationEvaluationId; + private LocalDateTime evaluationEndDate; private LocalDateTime expirationDate; private List commentsList; private String internalNote; diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java index f0be1236..81d4314d 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/ApplicationEvaluationResponse.java @@ -27,6 +27,6 @@ public class ApplicationEvaluationResponse { private Long protocolNumber; private String callName; private LocalDateTime submissionDate; - private LocalDateTime evaluationDate; + private LocalDateTime evaluationEndDate; private LocalDateTime callEndDate; } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index 57331e43..af46d7b5 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -25,6 +26,7 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findAllByApplicationEvaluationIdAndIsDeletedFalse(Long id); @@ -34,4 +36,19 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findByApplicationIdAndStatusInAndIsDeletedFalse(Long applicationId, List statuses); + @Query(value = "SELECT amr " + + "FROM ApplicationAmendmentRequestEntity amr " + + "WHERE amr.applicationEvaluationEntity.id = :id " + + "AND amr.isDeleted = false " + + "AND amr.applicationEvaluationEntity.isDeleted = false " + + "AND amr.status = :status") + List findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(Long id, String status); + + @Query("SELECT a FROM ApplicationAmendmentRequestEntity a " + + "WHERE a.applicationId = :applicationId " + + "AND a.isDeleted = false " + + "AND a.status <> 'CLOSE' " + + "AND a.endDate < :currentTime") + List findActiveAmendments(Long applicationId, LocalDateTime currentTime); + } diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java index 9ec88ffa..4e4069f3 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationEvaluationRepository.java @@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -21,5 +22,6 @@ public interface ApplicationEvaluationRepository extends JpaRepository findFirstByIsDeletedFalseOrderByCreatedDateDesc(); boolean existsByApplicationIdAndIsDeletedFalse(Long applicationId); - + @Query("SELECT a FROM ApplicationEvaluationEntity a WHERE a.isDeleted = false AND a.endDate < :currentDate") + List findAllByIsDeletedFalseAndEndDateBefore(@Param("currentDate") LocalDateTime currentDate); } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java new file mode 100644 index 00000000..9b424e29 --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java @@ -0,0 +1,29 @@ +package net.gepafin.tendermanagement.scheduler; + +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; + +import java.time.LocalDateTime; +import java.util.List; + +public class ApplicationEvaluationScheduler { + + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + + @Scheduled(cron = "0 0 1 * * ?") // Runs daily at midnight + public void updateExpiredEvaluations() { + LocalDateTime currentDate = LocalDateTime.now(); + List evaluations = applicationEvaluationRepository.findAllByIsDeletedFalseAndEndDateBefore(currentDate); + + for (ApplicationEvaluationEntity evaluation : evaluations) { + evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.EXPIRED.getValue()); + } + applicationEvaluationRepository.saveAll(evaluations); + } + } + diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java index 58908280..521726a9 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java @@ -1,20 +1,26 @@ package net.gepafin.tendermanagement.scheduler; +import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; import net.gepafin.tendermanagement.dao.EmailNotificationDao; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.UserRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Component public class NotificationScheduler { @@ -31,6 +37,12 @@ public class NotificationScheduler { @Autowired EmailNotificationDao emailNotificationDao; + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + @Scheduled(cron = "0 0 1 * * ?") void sendNotificationForRejectedApplicationToBeneficiary() { @@ -40,17 +52,18 @@ public class NotificationScheduler { LocalDateTime today = LocalDateTime.now(); for (ApplicationEntity application : applicationsList) { - ApplicationAmendmentRequestEntity amendmentRequest = getAmendmentRequestForApplication(application, amendmentRequestList); - - if (amendmentRequest != null) { - LocalDateTime requestDate = amendmentRequest.getStartDate(); - if (requestDate.plusDays(amendmentRequest.getResponseDays()).isBefore(today)) { - // Update the application status to REJECTED + List amendmentRequestEntities = applicationAmendmentRepository.findActiveAmendments(application.getId(), DateTimeUtil.DateServerToUTC(LocalDateTime.now())); + List applicationAmendmentRequestEntities = new ArrayList<>(); + if (amendmentRequestEntities != null && Boolean.FALSE.equals(amendmentRequestEntities.isEmpty())) { + for (ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity : amendmentRequestEntities) { + if (amendmentRequestEntities.size() == 1) { + applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(applicationAmendmentRequestEntity.getApplicationEvaluationEntity()); + } application.setStatus(ApplicationStatusTypeEnum.REJECTED.getValue()); applicationRepository.save(application); - amendmentRequest.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); - applicationAmendmentRepository.save(amendmentRequest); - emailNotificationDao.sendApplicationFailureNotificationEmail(amendmentRequest); + applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + applicationAmendmentRepository.save(applicationAmendmentRequestEntity); + emailNotificationDao.sendApplicationFailureNotificationEmail(applicationAmendmentRequestEntity); } } } 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 a7fe774d..faab8f35 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 @@ -1785,4 +1785,20 @@ + + + + + + + + + + + + + + + + diff --git a/src/main/resources/message_en.properties b/src/main/resources/message_en.properties index 87c95e39..4576117e 100644 --- a/src/main/resources/message_en.properties +++ b/src/main/resources/message_en.properties @@ -309,3 +309,6 @@ DD_MM_YYYY_HH_MM = dd_MM_yyyy HH:mm application.documents.not.found=No documents found for the application. beneficiary.call.duplicate = A preferred call with this call ID and company ID already exists for this user. company.id.required.for.preferred.call=Company ID is required when requesting only preferred calls. + +response.days.not.null=Response days should not be null and greater than zero. +application.cannot.approved.or.rejected=Application cannot be approved and rejected because amendment is active. diff --git a/src/main/resources/message_it.properties b/src/main/resources/message_it.properties index c4763ec7..937a2d21 100644 --- a/src/main/resources/message_it.properties +++ b/src/main/resources/message_it.properties @@ -304,3 +304,5 @@ reminder.email.sent.success.msg=Email di promemoria inviata con successo! application.documents.not.found=Nessun documento trovato per la domanda. beneficiary.call.duplicate = Una chiamata preferita con questo ID di chiamata e ID azienda esiste gi� per questo utente. company.id.required.for.preferred.call=ID azienda obbligatorio quando si richiedono solo chiamate preferite. +response.days.not.null=I giorni di risposta non devono essere nulli e maggiori di zero. +application.cannot.approved.or.rejected=La domanda non può essere approvata o rifiutata perché l'emendamento è attivo. From c1313f1591d79eb8a82fbffcf2c58a152685acac Mon Sep 17 00:00:00 2001 From: nisha Date: Tue, 26 Nov 2024 09:46:18 +0530 Subject: [PATCH 2/4] Updated code --- .../dao/AssignedApplicationsDao.java | 13 +++++++++++-- .../response/AssignedApplicationsResponse.java | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java index 1617b3e7..68cc26a7 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/AssignedApplicationsDao.java @@ -4,6 +4,7 @@ import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.entities.ApplicationEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.entities.AssignedApplicationsEntity; import net.gepafin.tendermanagement.entities.UserEntity; import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; @@ -11,6 +12,7 @@ import net.gepafin.tendermanagement.enums.AssignedApplicationEnum; import net.gepafin.tendermanagement.model.request.ApplicationEvaluationRequest; import net.gepafin.tendermanagement.model.request.AssignedApplicationsRequest; import net.gepafin.tendermanagement.model.response.AssignedApplicationsResponse; +import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; import net.gepafin.tendermanagement.repositories.ApplicationRepository; import net.gepafin.tendermanagement.repositories.AssignedApplicationsRepository; import net.gepafin.tendermanagement.service.ApplicationService; @@ -26,6 +28,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import static net.gepafin.tendermanagement.util.Utils.log; @@ -51,6 +54,9 @@ public class AssignedApplicationsDao { @Autowired private ApplicationEvaluationDao applicationEvaluationDao; + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; + public AssignedApplicationsResponse createAssignedApplications(Long applicationId, Long userId, UserEntity assignedByUser, AssignedApplicationsRequest assignedApplicationsRequest){ log.info("Assigning application to pre-Instructor with details: {}", applicationId,userId); @@ -71,8 +77,8 @@ public class AssignedApplicationsDao { applicationRepository.save(application); UserEntity user = userService.validateUser(userId); AssignedApplicationsEntity assignment = createAssignmentEntity(application, user.getId(), assignedByUser, assignedApplicationsRequest); + applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, new ApplicationEvaluationRequest(), assignment.getId()); AssignedApplicationsResponse assignApplicationToInstructorResponse = convertEntityToResponse(assignment); - applicationEvaluationDao.createOrUpdateApplicationEvaluation(user, new ApplicationEvaluationRequest(), assignApplicationToInstructorResponse.getId()); log.info("Application assigned succesfully {}", assignApplicationToInstructorResponse); return assignApplicationToInstructorResponse; } @@ -105,6 +111,7 @@ public class AssignedApplicationsDao { ApplicationEntity application = applicationService.validateApplication(assignedApplications.getApplication().getId()); String callName = application.getCall() != null ? application.getCall().getName() : ""; + Optional applicationEvaluationEntity=applicationEvaluationRepository.findByApplicationIdAndIsDeletedFalse(application.getId()); LocalDateTime callEndDate = application.getCall().getEndDate(); LocalDateTime callStartDate = application.getCall().getStartDate(); @@ -136,7 +143,9 @@ public class AssignedApplicationsDao { assignedApplicationsResponse.setSubmissionDate(submissionDate); assignedApplicationsResponse.setCallEndDate(callEndDate); assignedApplicationsResponse.setCallStartDate(callStartDate); - + if(applicationEvaluationEntity.isPresent()){ + assignedApplicationsResponse.setEvaluationEndDate(applicationEvaluationEntity.get().getEndDate()); + } return assignedApplicationsResponse; } diff --git a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java index 3affe42f..b975c150 100644 --- a/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java +++ b/src/main/java/net/gepafin/tendermanagement/model/response/AssignedApplicationsResponse.java @@ -21,6 +21,7 @@ public class AssignedApplicationsResponse extends BaseBean { private LocalDateTime callStartDate; private LocalDateTime callEndDate; private String companyName; + private LocalDateTime evaluationEndDate; } From 51998245d6724c7083e10fd1b1912d488cda188d Mon Sep 17 00:00:00 2001 From: harish Date: Thu, 28 Nov 2024 12:37:12 +0530 Subject: [PATCH 3/4] updated code for Amendment scheduler --- pom.xml | 5 + .../dao/ApplicationAmendmentRequestDao.java | 7 +- .../enums/UserActionContextEnum.java | 6 +- .../enums/UserActionLogsEnum.java | 3 +- ...ApplicationAmendmentRequestRepository.java | 21 ++- .../ApplicationAmendmentScheduler.java | 122 ++++++++++++++++++ .../ApplicationEvaluationScheduler.java | 89 ++++++++++--- .../scheduler/NotificationScheduler.java | 76 ----------- ...pplicationAmendmentRequestServiceImpl.java | 7 + .../tendermanagement/util/LoggingUtil.java | 9 +- .../gepafin/tendermanagement/util/Utils.java | 16 +++ 11 files changed, 256 insertions(+), 105 deletions(-) create mode 100644 src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java delete mode 100644 src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java diff --git a/pom.xml b/pom.xml index 08c677d0..f3424e44 100644 --- a/pom.xml +++ b/pom.xml @@ -225,6 +225,11 @@ 3.0.0 + + + org.springframework + spring-test + diff --git a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java index 2cf079bf..c9c19708 100644 --- a/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java +++ b/src/main/java/net/gepafin/tendermanagement/dao/ApplicationAmendmentRequestDao.java @@ -212,7 +212,7 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = new ApplicationAmendmentRequestEntity(); applicationAmendmentRequestEntity.setNote(applicationAmendmentRequest.getNote()); applicationAmendmentRequestEntity.setResponseDays(applicationAmendmentRequest.getResponseDays()); - if(applicationAmendmentRequest.getResponseDays()==null && applicationAmendmentRequest.getResponseDays() < 0){ + if(applicationAmendmentRequest.getResponseDays()==null || applicationAmendmentRequest.getResponseDays() < 0){ throw new CustomValidationException(Status.BAD_REQUEST,Translator.toLocale(GepafinConstant.RESPONSE_DAYS_NOT_NULL)); } applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now()).plusDays(applicationAmendmentRequest.getResponseDays())); @@ -897,7 +897,7 @@ public class ApplicationAmendmentRequestDao { ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity = validateApplicationAmendmentRequest(id); if (newResponseDays != null && newResponseDays > 0) { -ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); + ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClonedEntityForData(applicationAmendmentRequestEntity); Long currentResponseDays = applicationAmendmentRequestEntity.getResponseDays() != null ? applicationAmendmentRequestEntity.getResponseDays() : 0L; applicationAmendmentRequestEntity.setResponseDays(currentResponseDays + newResponseDays); applicationAmendmentRequestEntity.setEndDate(DateTimeUtil.DateServerToUTC(LocalDateTime.now().plusDays(applicationAmendmentRequestEntity.getResponseDays()))); @@ -1014,6 +1014,9 @@ ApplicationAmendmentRequestEntity oldApplicationAmendmentEntity = Utils.getClone ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(applicationEvaluationEntity); applicationEvaluationEntity.setEndDate(endDate); + if(applicationEvaluationEntity.getSuspendedDays() == null) { + applicationEvaluationEntity.setSuspendedDays(0L); + } applicationEvaluationEntity.setSuspendedDays(applicationEvaluationEntity.getSuspendedDays()+suspendedDays); ApplicationEvaluationEntity applicationEvaluation = applicationEvaluationRepository.save(applicationEvaluationEntity); diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java index 0a92143b..7023b40b 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionContextEnum.java @@ -147,7 +147,11 @@ public enum UserActionContextEnum { GET_FORM("GET_FORM"), CREATE_FORM("CREATE_FORM"), UPDATE_FORM("UPDATE_FORM"), - DELETE_FORM("DELETE_FORM"); + DELETE_FORM("DELETE_FORM"), + + /** scheduler action context **/ + AMENDMENT_EXPIRATION_SCHEDULER("AMENDMENT_EXPIRATION_SCHEDULER"), + EVALUATION_EXPIRATION_SCHEDULER("EVALUATION_EXPIRATION_SCHEDULER"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java index f68f6ae9..6fdd86f5 100644 --- a/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java +++ b/src/main/java/net/gepafin/tendermanagement/enums/UserActionLogsEnum.java @@ -10,7 +10,8 @@ public enum UserActionLogsEnum { VIEW("VIEW"), INSERT("INSERT"), DOWNLOAD("DOWNLOAD"), - UPLOAD("UPLOAD"); + UPLOAD("UPLOAD"), + SCHEDULER("SCHEDULER"); private final String value; diff --git a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java index af46d7b5..a5443dd3 100644 --- a/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java +++ b/src/main/java/net/gepafin/tendermanagement/repositories/ApplicationAmendmentRequestRepository.java @@ -1,6 +1,8 @@ package net.gepafin.tendermanagement.repositories; import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; @@ -9,6 +11,7 @@ import org.springframework.data.repository.query.Param; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; +import java.util.Set; public interface ApplicationAmendmentRequestRepository extends JpaRepository, JpaSpecificationExecutor { Optional findByIdAndIsDeletedFalse(Long id); @@ -45,10 +48,22 @@ public interface ApplicationAmendmentRequestRepository extends JpaRepository findAllByApplicationEvaluationIdAndStatusAndIsDeletedFalse(Long id, String status); @Query("SELECT a FROM ApplicationAmendmentRequestEntity a " + - "WHERE a.applicationId = :applicationId " + - "AND a.isDeleted = false " + + "WHERE a.isDeleted = false " + "AND a.status <> 'CLOSE' " + "AND a.endDate < :currentTime") - List findActiveAmendments(Long applicationId, LocalDateTime currentTime); + List findAmendmentsDueForExpiration(LocalDateTime currentTime); + + + + @Query("SELECT DISTINCT a.applicationEvaluationEntity " + + "FROM ApplicationAmendmentRequestEntity a " + + "WHERE a.applicationEvaluationEntity.id IN :applicationEvaluationIds " + + "AND a.isDeleted = false " + + "AND NOT EXISTS ( " + + " SELECT 1 FROM ApplicationAmendmentRequestEntity activeAmendment" + + " WHERE activeAmendment.applicationEvaluationEntity.id = a.applicationEvaluationEntity.id " + + " AND activeAmendment.status <> 'CLOSE' " + + " AND activeAmendment.isDeleted = false) ") + Set findEvaluationsWithoutActiveAmendmentsByIds(@Param("applicationEvaluationIds") Set applicationEvaluationIds); } diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java new file mode 100644 index 00000000..a3112a1c --- /dev/null +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationAmendmentScheduler.java @@ -0,0 +1,122 @@ +package net.gepafin.tendermanagement.scheduler; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import jakarta.servlet.http.HttpServletRequest; +import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; +import net.gepafin.tendermanagement.dao.EmailNotificationDao; +import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; +import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; +import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; +import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; +import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; +import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; +import net.gepafin.tendermanagement.util.LoggingUtil; +import net.gepafin.tendermanagement.util.Utils; + +@Component +public class ApplicationAmendmentScheduler { + + @Autowired + private HttpServletRequest httpServletRequest; + + @Autowired + private ApplicationAmendmentRequestRepository applicationAmendmentRepository; + + @Autowired + private EmailNotificationDao emailNotificationDao; + + @Autowired + private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; + + @Autowired + private LoggingUtil loggingUtil; + + private static final Logger log = LoggerFactory.getLogger(ApplicationAmendmentScheduler.class); + + @Scheduled(cron = "0 0 1 * * ?") + public void processAmendmentExpirationScheduler() { + log.info("Starting the Application Amendment Expiration scheduler."); + try { + + Utils.setHttpServletRequestForScheduler(); + + /** This code is responsible for creating user action logs for the "Application Amendment Expiration scheduler" operation. **/ + loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER).actionContext(UserActionContextEnum.AMENDMENT_EXPIRATION_SCHEDULER).build()); + + List amendmentRequestList = applicationAmendmentRepository + .findAmendmentsDueForExpiration( + DateTimeUtil.DateServerToUTC(LocalDateTime.now()).with(LocalTime.MIN).plusSeconds(5)); + processAmendmentsForExpiration(amendmentRequestList); + log.info("Application Amendment Expiration scheduler completed successfully."); + } catch (Exception e) { + log.error("An error occurred during the Application Amendment Expiration scheduler: {}", e.getMessage(), e); + } + Utils.clearHttpServletRequest(); + } + + private void processAmendmentsForExpiration(List amendmentRequests) { + + log.info("Starting the process of expiring application amendments."); + amendmentRequests.forEach(request -> { + try { + ApplicationAmendmentRequestEntity oldAmendmentRequestEntity = Utils.getClonedEntityForData(request); + request.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); + request = applicationAmendmentRepository.save(request); + + /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest).actionType(VersionActionTypeEnum.UPDATE).oldData(oldAmendmentRequestEntity).newData(request).build()); + + emailNotificationDao.sendApplicationFailureNotificationEmail(request); + log.info("Updated status to CLOSED for ApplicationAmendmentRequest with ID: {}", request.getId()); + } catch (Exception e) { + log.error("Error expiring ApplicationAmendmentRequest with ID {}: {}", request.getId(), e.getMessage(), + e); + } + }); + log.info("Completed the process of updating expiring application amendments."); + + log.info("Starting the process of updating EndDate in ApplicationEvaluations."); + try { + Set applicationEvaluationIds = amendmentRequests.stream() + .map(request -> request.getApplicationEvaluationEntity().getId()).collect(Collectors.toSet()); + + Set evaluationsWithoutActiveAmendmentList = applicationAmendmentRepository + .findEvaluationsWithoutActiveAmendmentsByIds(applicationEvaluationIds); + evaluationsWithoutActiveAmendmentList.forEach(evaluation -> { + try { + applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(evaluation); + log.info("Updated EndDate and suspension days for ApplicationEvaluation with ID: {}", + evaluation.getId()); + } catch (Exception e) { + log.error("Error updating EndDate for ApplicationEvaluation with ID {}: {}", evaluation.getId(), + e.getMessage(), e); + } + }); + + log.info("Completed the process of updating EndDate in ApplicationEvaluations."); + } catch (Exception e) { + log.error("An error occurred while updating EndDate in ApplicationEvaluations: {}", e.getMessage(), e); + } + + } + +} diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java index 54e641c9..94980dcd 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java @@ -3,42 +3,93 @@ package net.gepafin.tendermanagement.scheduler; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; import net.gepafin.tendermanagement.enums.ApplicationEvaluationStatusTypeEnum; +import net.gepafin.tendermanagement.enums.UserActionContextEnum; +import net.gepafin.tendermanagement.enums.UserActionLogsEnum; import net.gepafin.tendermanagement.enums.VersionActionTypeEnum; +import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; +import net.gepafin.tendermanagement.util.DateTimeUtil; import net.gepafin.tendermanagement.util.LoggingUtil; import net.gepafin.tendermanagement.util.Utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; +@Component public class ApplicationEvaluationScheduler { + @Autowired + private ApplicationEvaluationRepository applicationEvaluationRepository; - @Autowired - private ApplicationEvaluationRepository applicationEvaluationRepository; + @Autowired + private LoggingUtil loggingUtil; - @Autowired - private LoggingUtil loggingUtil; + @Autowired + private HttpServletRequest httpServletRequest; - @Autowired - private HttpServletRequest request; + private static final Logger log = LoggerFactory.getLogger(ApplicationEvaluationScheduler.class); - @Scheduled(cron = "0 0 1 * * ?") // Runs daily at midnight - public void updateExpiredEvaluations() { - LocalDateTime currentDate = LocalDateTime.now(); - List evaluations = applicationEvaluationRepository.findAllByIsDeletedFalseAndEndDateBefore(currentDate); + @Scheduled(cron = "0 0 2 * * ?") // Runs daily at midnight + public void updateExpiredEvaluations() { + log.info("Starting the Application Evaluation Expiration scheduler..."); + Utils.setHttpServletRequestForScheduler(); + try { + processExpiredEvaluation(); + log.info("Completed the process of updating expiring application evaluations."); + } catch (Exception e) { + log.error("An error occurred during the Application Evaluation Expiration scheduler: {}", e.getMessage(), + e); + } finally { + Utils.clearHttpServletRequest(); + } + } - for (ApplicationEvaluationEntity evaluation : evaluations) { - ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils.getClonedEntityForData(evaluation); - evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.EXPIRED.getValue()); + private void processExpiredEvaluation() { + log.info("Starting the process of expiring application evaluations."); - /** This code is responsible for adding a version history log for the "Update Application Amendment" operation. **/ - loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity).newData(evaluation).build()); - } - applicationEvaluationRepository.saveAll(evaluations); - } - } + // Logging user action for the scheduler operation + loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER) + .actionContext(UserActionContextEnum.EVALUATION_EXPIRATION_SCHEDULER).build()); + try { + List evaluations = applicationEvaluationRepository + .findAllByIsDeletedFalseAndEndDateBefore( + DateTimeUtil.DateServerToUTC(LocalDateTime.now()).with(LocalTime.MIN).plusSeconds(5)); + log.info("Found {} evaluations to process for expiration.", evaluations.size()); + + for (ApplicationEvaluationEntity evaluation : evaluations) { + try { + log.debug("Processing evaluation with ID: {}", evaluation.getId()); + + ApplicationEvaluationEntity oldApplicationEvaluationEntity = Utils + .getClonedEntityForData(evaluation); + + evaluation.setStatus(ApplicationEvaluationStatusTypeEnum.EXPIRED.getValue()); + evaluation = applicationEvaluationRepository.save(evaluation); + + // Logging version history for the update operation + loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(httpServletRequest) + .actionType(VersionActionTypeEnum.UPDATE).oldData(oldApplicationEvaluationEntity) + .newData(evaluation).build()); + + log.info("Updated evaluation status to EXPIRED for ID: {}", evaluation.getId()); + } catch (Exception e) { + log.error("Error processing evaluation with ID: {}. Error: {}", evaluation.getId(), e.getMessage(), + e); + } + } + } catch (Exception e) { + log.error("An error occurred while fetching evaluations for expiration. Error: {}", e.getMessage(), e); + } + + } +} diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java deleted file mode 100644 index 521726a9..00000000 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/NotificationScheduler.java +++ /dev/null @@ -1,76 +0,0 @@ -package net.gepafin.tendermanagement.scheduler; - -import net.gepafin.tendermanagement.dao.ApplicationAmendmentRequestDao; -import net.gepafin.tendermanagement.dao.EmailNotificationDao; -import net.gepafin.tendermanagement.entities.ApplicationAmendmentRequestEntity; -import net.gepafin.tendermanagement.entities.ApplicationEntity; -import net.gepafin.tendermanagement.entities.ApplicationEvaluationEntity; -import net.gepafin.tendermanagement.entities.UserEntity; -import net.gepafin.tendermanagement.enums.ApplicationAmendmentRequestEnum; -import net.gepafin.tendermanagement.enums.ApplicationStatusTypeEnum; -import net.gepafin.tendermanagement.repositories.ApplicationAmendmentRequestRepository; -import net.gepafin.tendermanagement.repositories.ApplicationEvaluationRepository; -import net.gepafin.tendermanagement.repositories.ApplicationRepository; -import net.gepafin.tendermanagement.repositories.UserRepository; -import net.gepafin.tendermanagement.util.DateTimeUtil; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -@Component -public class NotificationScheduler { - - @Autowired - UserRepository userRepository; - - @Autowired - ApplicationRepository applicationRepository; - - @Autowired - ApplicationAmendmentRequestRepository applicationAmendmentRepository; - - @Autowired - EmailNotificationDao emailNotificationDao; - - @Autowired - private ApplicationAmendmentRequestDao applicationAmendmentRequestDao; - - @Autowired - private ApplicationEvaluationRepository applicationEvaluationRepository; - - @Scheduled(cron = "0 0 1 * * ?") - void sendNotificationForRejectedApplicationToBeneficiary() { - - List applicationsList = applicationRepository.findByIsDeletedFalse(); - List amendmentRequestList = applicationAmendmentRepository.findByIsDeletedFalse(); - - LocalDateTime today = LocalDateTime.now(); - - for (ApplicationEntity application : applicationsList) { - List amendmentRequestEntities = applicationAmendmentRepository.findActiveAmendments(application.getId(), DateTimeUtil.DateServerToUTC(LocalDateTime.now())); - List applicationAmendmentRequestEntities = new ArrayList<>(); - if (amendmentRequestEntities != null && Boolean.FALSE.equals(amendmentRequestEntities.isEmpty())) { - for (ApplicationAmendmentRequestEntity applicationAmendmentRequestEntity : amendmentRequestEntities) { - if (amendmentRequestEntities.size() == 1) { - applicationAmendmentRequestDao.calculateEndDateAndSuspensionDays(applicationAmendmentRequestEntity.getApplicationEvaluationEntity()); - } - application.setStatus(ApplicationStatusTypeEnum.REJECTED.getValue()); - applicationRepository.save(application); - applicationAmendmentRequestEntity.setStatus(ApplicationAmendmentRequestEnum.CLOSE.getValue()); - applicationAmendmentRepository.save(applicationAmendmentRequestEntity); - emailNotificationDao.sendApplicationFailureNotificationEmail(applicationAmendmentRequestEntity); - } - } - } - } - - private ApplicationAmendmentRequestEntity getAmendmentRequestForApplication(ApplicationEntity application, List amendmentRequestList) { - - return amendmentRequestList.stream().filter(request -> request.getApplicationId().equals(application.getId())).findFirst().orElse(null); - } -} 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 4d3092a3..7329c5c3 100644 --- a/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java +++ b/src/main/java/net/gepafin/tendermanagement/service/impl/ApplicationAmendmentRequestServiceImpl.java @@ -20,6 +20,7 @@ import net.gepafin.tendermanagement.web.rest.api.errors.ResourceNotFoundExceptio import net.gepafin.tendermanagement.web.rest.api.errors.Status; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Optional; @@ -45,6 +46,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse createApplicationAmendmentRequest(HttpServletRequest request, Long applicationEvaluationId , ApplicationAmendmentRequest applicationAmendmentRequest) { Optional entityOptional = applicationEvaluationRepository.findByIdAndIsDeletedFalse(applicationEvaluationId); entityOptional.ifPresent(applicationEvaluationEntity -> validator.validatePreInstructor(request, applicationEvaluationEntity.getUserId())); @@ -52,6 +54,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public void deleteApplicationAmendmentRequest(HttpServletRequest request, Long id) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, @@ -86,6 +89,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse updateApplicationAmendment(HttpServletRequest request, Long id, ApplicationAmendmentRequestBean applicationAmendmentRequestBean) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestDao.validateApplicationAmendmentRequest(id); @@ -110,6 +114,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse closeAmendmentRequest(HttpServletRequest request, Long id, CloseAmendmentRequest closeAmendmentRequest) { ApplicationAmendmentRequestEntity amendment = applicationAmendmentRequestRepository.findByIdAndIsDeletedFalse(id) .orElseThrow(() -> new ResourceNotFoundException(Status.NOT_FOUND, @@ -123,6 +128,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse extendResponseDays(HttpServletRequest request, Long id, Long addedDays) { UserEntity user= validator.validateUser(request); return applicationAmendmentRequestDao.extendResponseDays(id, addedDays); @@ -132,6 +138,7 @@ public class ApplicationAmendmentRequestServiceImpl implements ApplicationAmendm return applicationAmendmentRequestDao.getAmendmentByApplicationId(request,applicationId,statuses); } @Override + @Transactional(rollbackFor = Exception.class) public ApplicationAmendmentRequestResponse updateApplicationAmendmentStatus(HttpServletRequest request, Long applicationAmendmentId, ApplicationAmendmentRequestEnum status) { return applicationAmendmentRequestDao.updateApplicationAmendmentStatus(applicationAmendmentId, status); diff --git a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java index 53ed01cb..319795ec 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java +++ b/src/main/java/net/gepafin/tendermanagement/util/LoggingUtil.java @@ -134,8 +134,12 @@ public class LoggingUtil { try { VersionHistoryEntity history = new VersionHistoryEntity(); String token = tokenProvider.extractTokenFromRequest(versionHistoryRequest.getRequest()); - Claims claims = tokenProvider.getClaimsFromToken(token); - Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + if(versionHistoryRequest.getRequest() != null && token != null) + { + Claims claims = tokenProvider.getClaimsFromToken(token); + Long userId = claims.get(GepafinConstant.USER_ID, Long.class); + history.setUserId(userId); + } String oldData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getOldData()); String newData = Utils.convertEntityToJsonForLogging(versionHistoryRequest.getNewData()); history.setUserActionId(userActionId); @@ -144,7 +148,6 @@ public class LoggingUtil { history.setNewData(newData); history.setRecordId(recordId); history.setTableName(tableName); - history.setUserId(userId); versionHistoryRepository.save(history); } catch (Exception e) { log.error("Error logging version history: {}", e.getMessage(), e); diff --git a/src/main/java/net/gepafin/tendermanagement/util/Utils.java b/src/main/java/net/gepafin/tendermanagement/util/Utils.java index 4949e5d5..7524c306 100644 --- a/src/main/java/net/gepafin/tendermanagement/util/Utils.java +++ b/src/main/java/net/gepafin/tendermanagement/util/Utils.java @@ -46,6 +46,9 @@ import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientNotFoundExcep import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientUnauthorizedException; import net.gepafin.tendermanagement.web.rest.api.errors.FeignClientValidationException; import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; @@ -564,4 +567,17 @@ 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(); + } } From 35669bae3969f8fe107631d2a970901a71ef3687 Mon Sep 17 00:00:00 2001 From: nisha Date: Thu, 28 Nov 2024 12:42:20 +0530 Subject: [PATCH 4/4] Update code --- .../ApplicationEvaluationScheduler.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java index 94980dcd..a0444349 100644 --- a/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java +++ b/src/main/java/net/gepafin/tendermanagement/scheduler/ApplicationEvaluationScheduler.java @@ -40,8 +40,16 @@ public class ApplicationEvaluationScheduler { @Scheduled(cron = "0 0 2 * * ?") // Runs daily at midnight public void updateExpiredEvaluations() { log.info("Starting the Application Evaluation Expiration scheduler..."); - Utils.setHttpServletRequestForScheduler(); try { + + Utils.setHttpServletRequestForScheduler(); + + // Logging user action for the scheduler operation + loggingUtil.logUserActionWithoutToken( + UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER) + .actionContext(UserActionContextEnum.EVALUATION_EXPIRATION_SCHEDULER).build()); + + processExpiredEvaluation(); log.info("Completed the process of updating expiring application evaluations."); } catch (Exception e) { @@ -55,11 +63,7 @@ public class ApplicationEvaluationScheduler { private void processExpiredEvaluation() { log.info("Starting the process of expiring application evaluations."); - // Logging user action for the scheduler operation - loggingUtil.logUserActionWithoutToken( - UserActionRequest.builder().request(httpServletRequest).actionType(UserActionLogsEnum.SCHEDULER) - .actionContext(UserActionContextEnum.EVALUATION_EXPIRATION_SCHEDULER).build()); - + try { List evaluations = applicationEvaluationRepository .findAllByIsDeletedFalseAndEndDateBefore(