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); } } }