package net.gepafin.tendermanagement.scheduler; import jakarta.servlet.http.HttpServletRequest; import net.gepafin.tendermanagement.dao.NotificationDao; import net.gepafin.tendermanagement.entities.CompanyDocumentEntity; import net.gepafin.tendermanagement.entities.ExpirationConfigEntity; import net.gepafin.tendermanagement.enums.*; import net.gepafin.tendermanagement.model.request.UserActionRequest; import net.gepafin.tendermanagement.model.request.VersionHistoryRequest; import net.gepafin.tendermanagement.repositories.CompanyDocumentRepository; import net.gepafin.tendermanagement.repositories.ExpirationConfigRepository; 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.util.List; @Component public class CompanyDocumentExpirationScheduler { @Autowired private CompanyDocumentRepository companyDocumentRepository; @Autowired private NotificationDao notificationDao; @Autowired private LoggingUtil loggingUtil; @Autowired private HttpServletRequest request; @Autowired private ExpirationConfigRepository expirationConfigRepository; private static final Logger log = LoggerFactory.getLogger(ExpirationScheduler.class); @Scheduled(cron = "0 0 4 * * ?") public void processDocumentExpiration(){ log.info("Starting the Document Expiration scheduler..."); try { Utils.setHttpServletRequestForScheduler(); // Logging user action for the scheduler operation loggingUtil.logUserActionWithoutToken( UserActionRequest.builder().request(request).actionType(UserActionLogsEnum.SCHEDULER) .actionContext(UserActionContextEnum.COMPANY_DOCUMENT_EXPIRATION_SCHEDULER).build()); log.info("Starting processing expiration notifications for document"); processExpirationReminder(ExpirationTypeEnum.COMPANY_DOCUMENT); updateExpiredDocuments(); log.info("Expiration scheduler completed successfully."); } catch (Exception e){ log.error("An error occurred during the Notification Expiration Scheduler of Document: {}", e.getMessage(), e); } } private void processExpirationReminder(ExpirationTypeEnum typeEnum){ List configEntities = expirationConfigRepository.findByTypeAndIsDeletedFalse(typeEnum.getValue()); for (ExpirationConfigEntity config : configEntities){ Long daysBefore = config.getIntervalDays(); LocalDateTime now = LocalDateTime.now(); LocalDateTime startDate = now.plusDays(daysBefore).withHour(0).withMinute(0).withSecond(0).withNano(2); LocalDateTime endDate = startDate.plusDays(1).minusNanos(2); processDocumentExpiration(startDate, endDate, daysBefore); } } private void processDocumentExpiration(LocalDateTime startDate, LocalDateTime endDate, Long daysBefore){ List expiringDocuments = companyDocumentRepository.findExpiringBetween(startDate, endDate); for (CompanyDocumentEntity document : expiringDocuments) { notificationDao.sendNotificationToBeneficiaryForDocumentExpiration(document, NotificationTypeEnum.COMPANY_DOCUMENT_EXPIRATION_REMINDER); updateDocumentStatus(document, CompanyDocumentStatusEnum.DUE.getValue()); } } private void updateDocumentStatus(CompanyDocumentEntity companyDocument,String status) { CompanyDocumentEntity oldCompanyDocumentEntity = Utils.getClonedEntityForData(companyDocument); companyDocument.setStatus(status); companyDocumentRepository.save(companyDocument); // Logging version history for the update operation loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request) .actionType(VersionActionTypeEnum.UPDATE).oldData(oldCompanyDocumentEntity) .newData(companyDocument).build()); log.info("Updated document status for document: {}", companyDocument.getFileName()); } private void updateExpiredDocuments() { LocalDateTime now = LocalDateTime.now(); List expiredDocuments = companyDocumentRepository.findByExpirationDateBeforeAndIsDeletedFalse(now); for (CompanyDocumentEntity document : expiredDocuments) { updateDocumentStatus(document, CompanyDocumentStatusEnum.EXPIRED.getValue()); } } }