package ru.ulstu.timeline.service; import com.google.common.collect.ImmutableMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import ru.ulstu.core.util.DateUtils; import ru.ulstu.timeline.model.Event; import ru.ulstu.timeline.model.PeriodEvent; import ru.ulstu.user.service.MailService; import java.util.Date; import java.util.List; import java.util.Map; @Service public class EventScheduler { private final Logger log = LoggerFactory.getLogger(EventScheduler.class); private final EventService eventService; private final MailService mailService; public EventScheduler(EventService eventService, MailService mailService) { this.eventService = eventService; this.mailService = mailService; } @Scheduled(cron = "0 0 8 * * ?") public void sendNotifications() { List events = eventService.findByCurrentDate(); events.forEach(event -> { Map variables = ImmutableMap.of("description", event.getDescription()); event.getRecipients() .forEach(recipient -> mailService.sendEmailFromTemplate(variables, recipient, "eventNotification", event.getTitle())); }); } @Scheduled(cron = "0 0 * * * ?") public void checkPeriodEvents() { log.debug("EventScheduler.checkPeriodEvents started"); //TODO: filter for (Event event : eventService.findAll()) { if (halfOfThePeriodHasPassed(event)) { eventService.createBasedOn(event, DateUtils.addDays(event.getExecuteDate(), getShiftInDays(event.getPeriod()))); } } log.debug("EventScheduler.checkPeriodEvents finished"); } private int getShiftInDays(PeriodEvent periodEvent) { switch (periodEvent) { case EVERY_DAY: return periodEvent.getPeriod().getDays(); case EVERY_WEEK: return periodEvent.getPeriod().getDays(); case EVERY_MONTH: return periodEvent.getPeriod().getMonths() * 30; case EVERY_YEAR: return periodEvent.getPeriod().getYears() * 365; default: throw new RuntimeException("period event not exists"); } } private boolean halfOfThePeriodHasPassed(Event event) { return event.getPeriod() != null && event.getChild() == null && new Date().after( DateUtils.addDays(event.getExecuteDate(), (int) Math.round((double) getShiftInDays(event.getPeriod()) / 2))); } }