package ru.ulstu.conference.service; import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.ui.ModelMap; import org.springframework.validation.Errors; import ru.ulstu.conference.model.Conference; import ru.ulstu.conference.model.ConferenceDto; import ru.ulstu.conference.model.ConferenceFilterDto; import ru.ulstu.conference.model.ConferenceUser; import ru.ulstu.conference.repository.ConferenceRepository; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.deadline.service.DeadlineService; import ru.ulstu.name.BaseService; import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.service.PaperService; import ru.ulstu.ping.model.Ping; import ru.ulstu.ping.service.PingService; import ru.ulstu.timeline.service.EventService; import ru.ulstu.user.model.User; import ru.ulstu.user.service.UserService; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Collections; import java.util.stream.Collectors; import static org.springframework.util.ObjectUtils.isEmpty; import static ru.ulstu.core.util.StreamApiUtils.convert; @Service public class ConferenceService extends BaseService { private final static int MAX_DISPLAY_SIZE = 40; private final ConferenceRepository conferenceRepository; private final ConferenceUserService conferenceUserService; private final DeadlineService deadlineService; private final PaperService paperService; private final UserService userService; private final PingService pingService; private final ConferenceNotificationService conferenceNotificationService; private final EventService eventService; public ConferenceService(ConferenceRepository conferenceRepository, ConferenceUserService conferenceUserService, DeadlineService deadlineService, PaperService paperService, UserService userService, PingService pingService, ConferenceNotificationService conferenceNotificationService, EventService eventService) { this.baseRepository = conferenceRepository; this.conferenceRepository = conferenceRepository; this.conferenceUserService = conferenceUserService; this.deadlineService = deadlineService; this.paperService = paperService; this.userService = userService; this.pingService = pingService; this.conferenceNotificationService = conferenceNotificationService; this.eventService = eventService; } public ConferenceDto getExistConferenceById(Integer id) { ConferenceDto conferenceDto = new ConferenceDto(conferenceRepository.findOne(id)); conferenceDto.setNotSelectedPapers(getNotSelectPapers(conferenceDto.getPaperIds())); conferenceDto.setDisabledTakePart(isCurrentUserParticipant(conferenceDto.getUsers())); return conferenceDto; } public ConferenceDto getNewConference() { ConferenceDto conferenceDto = new ConferenceDto(); conferenceDto.setNotSelectedPapers(getNotSelectPapers(new ArrayList<>())); return conferenceDto; } public List findAll() { return conferenceRepository.findAll(new Sort(Sort.Direction.DESC, "beginDate")); } public List findAllDto() { List conferences = convert(findAll(), ConferenceDto::new); conferences.forEach(conferenceDto -> conferenceDto.setTitle(StringUtils.abbreviate(conferenceDto.getTitle(), MAX_DISPLAY_SIZE))); return conferences; } public boolean save(ConferenceDto conferenceDto, Errors errors) throws IOException { conferenceDto.setName(conferenceDto.getTitle()); filterEmptyDeadlines(conferenceDto); checkEmptyFieldsOfDeadline(conferenceDto, errors); checkEmptyFieldsOfDates(conferenceDto, errors); checkUniqueName(conferenceDto, errors, conferenceDto.getId(), "title", "Конференция с таким именем уже существует"); if (errors.hasErrors()) { return false; } if (isEmpty(conferenceDto.getId())) { create(conferenceDto); } else { update(conferenceDto); } return true; } @Transactional public Conference create(ConferenceDto conferenceDto) throws IOException { Conference newConference = copyFromDto(new Conference(), conferenceDto); newConference = conferenceRepository.save(newConference); conferenceNotificationService.sendCreateNotification(newConference); eventService.createFromObject(newConference, Collections.emptyList(), false, "конференции"); return newConference; } @Transactional public Conference update(ConferenceDto conferenceDto) throws IOException { Conference conference = conferenceRepository.findOne(conferenceDto.getId()); List oldDeadlines = conference.getDeadlines().stream() .map(this::copyDeadline) .collect(Collectors.toList()); Date oldBeginDate = conference.getBeginDate(); Date oldEndDate = conference.getEndDate(); conferenceRepository.save(copyFromDto(conference, conferenceDto)); eventService.updateConferenceDeadlines(conference); sendNotificationAfterUpdateDeadlines(conference, oldDeadlines); if (!conference.getBeginDate().equals(oldBeginDate) || !conference.getEndDate().equals(oldEndDate)) { conferenceNotificationService.updateConferencesDatesNotification(conference, oldBeginDate, oldEndDate); } conferenceDto.getRemovedDeadlineIds().forEach(deadlineService::remove); return conference; } @Transactional public boolean delete(Integer conferenceId) { if (conferenceRepository.exists(conferenceId)) { eventService.removeConferencesEvent(conferenceRepository.findOne(conferenceId)); conferenceRepository.delete(conferenceId); return true; } return false; } public ConferenceDto addDeadline(ConferenceDto conferenceDto) { conferenceDto.getDeadlines().add(new Deadline()); return conferenceDto; } public ConferenceDto removeDeadline(ConferenceDto conferenceDto, Integer deadlineIndex) throws IOException { if (conferenceDto.getDeadlines().get(deadlineIndex).getId() != null) { conferenceDto.getRemovedDeadlineIds().add(conferenceDto.getDeadlines().get(deadlineIndex).getId()); } conferenceDto.getDeadlines().remove((int) deadlineIndex); return conferenceDto; } public ConferenceDto addPaper(ConferenceDto conferenceDto) { Paper paper = new Paper(); paper.setTitle(userService.getCurrentUser().getLastName() + "_" + conferenceDto.getTitle() + "_" + (new Date()).getTime()); paper.setStatus(Paper.PaperStatus.DRAFT); conferenceDto.getPapers().add(paper); return conferenceDto; } public ConferenceDto removePaper(ConferenceDto conferenceDto, Integer paperIndex) throws IOException { Paper removedPaper = conferenceDto.getPapers().remove((int) paperIndex); if (removedPaper.getId() != null) { conferenceDto.getNotSelectedPapers().add(removedPaper); } return conferenceDto; } public ConferenceDto takePart(ConferenceDto conferenceDto) throws IOException { conferenceDto.getUsers().add(new ConferenceUser(userService.getCurrentUser())); conferenceDto.setDisabledTakePart(true); return conferenceDto; } private List getNotSelectPapers(List paperIds) { return paperService.findAllNotSelect(paperIds); } public List getAllUsers() { return userService.findAll(); } public List getAllParticipations() { return Arrays.asList(ConferenceUser.Participation.values()); } public List getAllDeposit() { return Arrays.asList(ConferenceUser.Deposit.values()); } private Conference copyFromDto(Conference conference, ConferenceDto conferenceDto) throws IOException { conference.setTitle(conferenceDto.getTitle()); conference.setDescription(conferenceDto.getDescription()); conference.setUrl(conferenceDto.getUrl()); conference.setBeginDate(conferenceDto.getBeginDate()); conference.setEndDate(conferenceDto.getEndDate()); conference.getPapers().clear(); conferenceDto.getPapers().forEach(paper -> conference.getPapers().add(paper.getId() != null ? paperService.findPaperById(paper.getId()) : paperService.create(paper))); conference.setDeadlines(deadlineService.saveOrCreate(conferenceDto.getDeadlines())); conference.setUsers(conferenceUserService.saveOrCreate(conferenceDto.getUsers())); if (conferenceDto.getPaperIds() != null && !conferenceDto.getPaperIds().isEmpty()) { conferenceDto.getPaperIds().forEach(paperId -> conference.getPapers().add(paperService.findPaperById(paperId))); } return conference; } private boolean isCurrentUserParticipant(List conferenceUsers) { return conferenceUsers.stream().anyMatch(participant -> participant.getUser().equals(userService.getCurrentUser())); } public List filter(ConferenceFilterDto conferenceFilterDto) { return convert(conferenceRepository.findByUserAndYear( conferenceFilterDto.getFilterUserId() == null ? null : userService.findById(conferenceFilterDto.getFilterUserId()), conferenceFilterDto.getYear()), ConferenceDto::new); } public List findAllActiveDto() { return convert(findAllActive(), ConferenceDto::new); } private List findAllActive() { return conferenceRepository.findAllActive(new Date()); } public boolean isAttachedToConference(Integer paperId) { return conferenceRepository.isPaperAttached(paperId); } @Transactional public Ping ping(ConferenceDto conferenceDto) throws IOException { Ping ping = pingService.addPing(findOne(conferenceDto.getId())); conferenceRepository.updatePingConference(conferenceDto.getId()); return ping; } private Conference findOne(Integer conferenceId) { return conferenceRepository.findOne(conferenceId); } public void setChartData(ModelMap modelMap) { //first, add the regional sales Integer northeastSales = 17089; Integer westSales = 10603; Integer midwestSales = 5223; Integer southSales = 10111; modelMap.addAttribute("northeastSales", northeastSales); modelMap.addAttribute("southSales", southSales); modelMap.addAttribute("midwestSales", midwestSales); modelMap.addAttribute("westSales", westSales); //now add sales by lure type List inshoreSales = Arrays.asList(4074, 3455, 4112); List nearshoreSales = Arrays.asList(3222, 3011, 3788); List offshoreSales = Arrays.asList(7811, 7098, 6455); modelMap.addAttribute("inshoreSales", inshoreSales); modelMap.addAttribute("nearshoreSales", nearshoreSales); modelMap.addAttribute("offshoreSales", offshoreSales); } private void sendNotificationAfterUpdateDeadlines(Conference conference, List oldDeadlines) { if (oldDeadlines.size() != conference.getDeadlines().size()) { conferenceNotificationService.updateDeadlineNotification(conference); return; } if (conference.getDeadlines() .stream() .filter(deadline -> !oldDeadlines.contains(deadline)) .count() > 0) { conferenceNotificationService.updateDeadlineNotification(conference); } } private Deadline copyDeadline(Deadline oldDeadline) { Deadline newDeadline = new Deadline(oldDeadline.getDate(), oldDeadline.getDescription()); newDeadline.setId(oldDeadline.getId()); return newDeadline; } public void checkEmptyFieldsOfDeadline(ConferenceDto conferenceDto, Errors errors) { for (Deadline deadline : conferenceDto.getDeadlines()) { if (deadline.getDate() == null || deadline.getDescription().isEmpty()) { errors.rejectValue("deadlines", "errorCode", "Все поля дедлайна должны быть заполнены"); } } } private void checkEmptyFieldsOfDates(ConferenceDto conferenceDto, Errors errors) { if (conferenceDto.getBeginDate() == null || conferenceDto.getEndDate() == null) { errors.rejectValue("beginDate", "errorCode", "Даты должны быть заполнены"); } } public void filterEmptyDeadlines(ConferenceDto conferenceDto) { conferenceDto.setDeadlines(conferenceDto.getDeadlines().stream() .filter(dto -> dto.getDate() != null || !org.springframework.util.StringUtils.isEmpty(dto.getDescription())) .collect(Collectors.toList())); } public Conference getActiveConferenceByUser(User user) { return conferenceRepository.findActiveByUser(user); } }