package ru.ulstu.conference.service; import com.google.common.collect.ImmutableMap; import org.springframework.stereotype.Service; import ru.ulstu.conference.model.Conference; import ru.ulstu.core.util.DateUtils; import ru.ulstu.ping.service.PingService; import ru.ulstu.user.service.MailService; import ru.ulstu.user.service.UserService; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Map; @Service public class ConferenceNotificationService { private final static int YESTERDAY = -1; private final static int DAYS_TO_DEADLINE_NOTIFICATION = 7; private final static String TEMPLATE_PING = "conferencePingNotification"; private final static String TEMPLATE_DEADLINE = "conferenceDeadlineNotification"; private final static String TEMPLATE_CREATE = "conferenceCreateNotification"; private final static String TEMPLATE_UPDATE_DEADLINES = "conferenceUpdateDeadlinesNotification"; private final static String TEMPLATE_UPDATE_DATES = "conferenceUpdateDatesNotification"; private final static String TITLE_PING = "Обратите внимание на конференцию: %s"; private final static String TITLE_DEADLINE = "Приближается дедлайн конференции: %s"; private final static String TITLE_CREATE = "Создана новая конференция: %s"; private final static String TITLE_UPDATE_DEADLINES = "Изменения дедлайнов в конференции: %s"; private final static String TITLE_UPDATE_DATES = "Изменение дат проведения конференции: %s"; private final MailService mailService; private final UserService userService; private final PingService pingService; public ConferenceNotificationService(MailService mailService, UserService userService, PingService pingService) { this.mailService = mailService; this.userService = userService; this.pingService = pingService; } public void sendDeadlineNotifications(List conferences) { Date now = DateUtils.addDays(new Date(), DAYS_TO_DEADLINE_NOTIFICATION); conferences .stream() .filter(conference -> needToSendDeadlineNotification(conference, now)) .forEach(this::sendMessageDeadline); } private boolean needToSendDeadlineNotification(Conference conference, Date compareDate) { return (conference.getNextDeadline().isPresent()) && conference.getNextDeadline().get().getDate().after(new Date()) && conference.getNextDeadline().get().getDate().before(compareDate); } private void sendMessageDeadline(Conference conference) { Map variables = ImmutableMap.of("conference", conference); sendForAllParticipants(variables, conference, TEMPLATE_DEADLINE, String.format(TITLE_DEADLINE, conference.getTitle())); } public void sendCreateNotification(Conference conference) { Map variables = ImmutableMap.of("conference", conference); sendForAllUsers(variables, TEMPLATE_CREATE, String.format(TITLE_CREATE, conference.getTitle())); } public void updateDeadlineNotification(Conference conference) { Map variables = ImmutableMap.of("conference", conference); sendForAllParticipants(variables, conference, TEMPLATE_UPDATE_DEADLINES, String.format(TITLE_UPDATE_DEADLINES, conference.getTitle())); } public void updateConferencesDatesNotification(Conference conference, Date oldBeginDate, Date oldEndDate) { Map variables = ImmutableMap.of("conference", conference, "oldBeginDate", oldBeginDate, "oldEndDate", oldEndDate); sendForAllParticipants(variables, conference, TEMPLATE_UPDATE_DATES, String.format(TITLE_UPDATE_DATES, conference.getTitle())); } private void sendForAllUsers(Map variables, String template, String title) { userService.findAll().forEach(user -> mailService.sendEmailFromTemplate(variables, user, template, title)); } private void sendForAllParticipants(Map variables, Conference conference, String template, String title) { conference.getUsers().forEach(conferenceUser -> mailService.sendEmailFromTemplate(variables, conferenceUser.getUser(), template, title)); } public void sendPingNotifications(List conferences) { Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.DAY_OF_MONTH, YESTERDAY); conferences .stream() .filter(conference -> { Integer pingCount = pingService.countPingYesterday(conference, calendar); return needToSendPingNotification(conference, pingCount); }) .forEach(this::sendMessagePing); } private boolean needToSendPingNotification(Conference conference, Integer pingCount) { if (pingCount > 0) { conference.setPing((Integer) pingCount); return true; } return false; } private void sendMessagePing(Conference conference) { Map variables = ImmutableMap.of("conference", conference); sendForAllParticipants(variables, conference, TEMPLATE_PING, String.format(TITLE_PING, conference.getTitle())); } }