package ru.ulstu.activity.paper.service; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.ulstu.activity.common.service.ActivityService; import ru.ulstu.activity.deadline.model.Deadline; import ru.ulstu.activity.deadline.service.DeadlineService; import ru.ulstu.activity.file.model.FileDataDto; import ru.ulstu.activity.file.service.FileService; import ru.ulstu.activity.paper.model.Paper; import ru.ulstu.activity.paper.model.PaperDashboardDto; import ru.ulstu.activity.paper.model.PaperDto; import ru.ulstu.activity.paper.model.PaperFilterListDto; import ru.ulstu.activity.paper.model.PaperListDto; import ru.ulstu.activity.paper.model.PaperStatusDto; import ru.ulstu.activity.paper.model.PaperTypeDto; import ru.ulstu.activity.ping.service.PingService; import ru.ulstu.activity.timeline.model.Event; import ru.ulstu.activity.timeline.service.EventService; import ru.ulstu.core.jpa.OffsetablePageRequest; import ru.ulstu.core.model.response.PageableItems; import ru.ulstu.user.model.User; import ru.ulstu.user.service.UserService; import javax.persistence.EntityNotFoundException; import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import static java.util.stream.Collectors.toList; import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty; import static org.springframework.util.ObjectUtils.isEmpty; import static ru.ulstu.activity.paper.model.Paper.PaperStatus.ATTENTION; import static ru.ulstu.activity.paper.model.Paper.PaperStatus.COMPLETED; import static ru.ulstu.activity.paper.model.Paper.PaperStatus.DRAFT; import static ru.ulstu.activity.paper.model.Paper.PaperStatus.FAILED; import static ru.ulstu.activity.paper.model.Paper.PaperStatus.ON_PREPARATION; import static ru.ulstu.activity.paper.model.Paper.PaperType.OTHER; import static ru.ulstu.core.util.StreamApiUtils.convert; import static ru.ulstu.core.util.StreamApiUtils.convertPageable; @Service public class PaperService extends ActivityService { private final PaperNotificationService paperNotificationService; private final PaperRepository paperRepository; private final UserService userService; private final DeadlineService deadlineService; private final FileService fileService; private final EventService eventService; private final PingService pingService; private Paper.PaperStatus oldStatus; private Set oldAuthors; public PaperService(PaperRepository paperRepository, FileService fileService, PaperNotificationService paperNotificationService, UserService userService, DeadlineService deadlineService, EventService eventService, PingService pingService) { super(paperRepository, paperNotificationService, pingService, eventService); this.paperRepository = paperRepository; this.fileService = fileService; this.paperNotificationService = paperNotificationService; this.userService = userService; this.deadlineService = deadlineService; this.eventService = eventService; this.pingService = pingService; } public PageableItems findAllActiveDto(int offset, int count) { return convertPageable(findAllActive(offset, count), PaperDashboardDto::new); } public PageableItems findAll(int offset, int count) { final Page page = paperRepository.findAll(new OffsetablePageRequest(offset, count)); return new PageableItems<>(page.getTotalElements(), sortPapers(page.getContent())); } @Override protected PaperListDto getActivityListDto(Paper entity) { return new PaperListDto(entity); } @Override protected Paper getNewActivity() { return new Paper(); } @Override protected PaperDto getNewActivityDto(Paper entity) { return new PaperDto(entity); } private PageableItems findAllActive(int offset, int count) { Page activePapersPage = paperRepository.findAllWithoutStatuses(new OffsetablePageRequest(offset, count), COMPLETED, FAILED); return new PageableItems<>(activePapersPage.getTotalElements(), sortPapers(activePapersPage.getContent())); } @Override protected List getEvents(Paper entity) { return eventService.findByPaper(entity); } @Transactional public PaperDto update(PaperDto paperDto) { Paper paper = findById(paperDto.getId()); oldStatus = paper.getStatus(); oldAuthors = new HashSet<>(paper.getAuthors()); //TODO: move to service if (paperDto.getFiles() != null) { for (FileDataDto file : paperDto.getFiles().stream() .filter(f -> f.isDeleted() && f.getId() != null) .collect(toList())) { fileService.delete(file.getId()); } } return new PaperDto(update(copyFromDto(paper, paperDto))); } protected Paper copyFromDto(Paper paper, PaperDto paperDto) { paper.setComment(paperDto.getComment()); paper.setUrl(paperDto.getUrl()); paper.setCreateDate(paper.getCreateDate() == null ? new Date() : paper.getCreateDate()); paper.setLocked(paperDto.getLocked()); paper.setStatus(paperDto.getStatus() == null ? DRAFT : paperDto.getStatus()); paper.setType(paperDto.getType() == null ? OTHER : paperDto.getType()); paper.setTitle(paperDto.getTitle()); paper.setUpdateDate(new Date()); paper.setDeadlines(deadlineService.saveOrCreate(paperDto.getDeadlines())); //TODO: move to service try { if (paperDto.getFiles() != null) { paper.setFiles(fileService.saveOrCreate(paperDto.getFiles().stream() .filter(f -> !f.isDeleted()) .collect(toList()))); } } catch (IOException ex) { throw new RuntimeException(ex); } paper.getAuthors().clear(); if (isNotEmpty(paperDto.getAuthors())) { paperDto.getAuthors().forEach(authors -> paper.getAuthors().add(userService.findById(authors.getId()))); } return paper; } @Transactional public boolean delete(Integer paperId) { Paper paper = paperRepository.getOne(paperId); paperRepository.delete(paper); return true; } public List getPaperStatuses() { return convert(Arrays.asList(Paper.PaperStatus.values()), PaperStatusDto::new); } public List getPaperTypes() { return convert(Arrays.asList(Paper.PaperType.values()), PaperTypeDto::new); } @Transactional public Paper create(String title, User user, Date deadlineDate) { Paper paper = new Paper(); paper.setTitle(title); paper.getAuthors().add(user); paper.getDeadlines().add(new Deadline(deadlineDate, "первый дедлайн")); paper.setCreateDate(new Date()); paper.setUpdateDate(new Date()); paper.setStatus(DRAFT); paper.setType(OTHER); return create(paper); } public List filter(PaperFilterListDto filterDto) { return convert(sortPapers(paperRepository.filter( filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()), filterDto.getYear())), PaperListDto::new); } private List sortPapers(List papers) { return papers.stream().sorted((paper1, paper2) -> { int statusCompareResult = Integer.valueOf(Arrays.asList(Paper.PaperStatus.values()).indexOf(paper1.getStatus())) .compareTo(Arrays.asList(Paper.PaperStatus.values()).indexOf(paper2.getStatus())); if (statusCompareResult != 0) { return statusCompareResult; } return paper1.getTitle().compareTo(paper2.getTitle()); }).collect(toList()); } public void closeFailedPapers() { List papers = paperRepository.findAll() .stream() .filter(paper -> paper.lastDeadlineFailed() && (paper.getStatus() == ON_PREPARATION || paper.getStatus() == DRAFT || paper.getStatus() == ATTENTION)) .collect(toList()); papers.forEach(paper -> { Paper.PaperStatus oldStatus = paper.getStatus(); paper.setStatus(Paper.PaperStatus.FAILED); paperRepository.save(paper); paperNotificationService.sendFailedNotification(paper, oldStatus); }); } public void save(PaperDto paperDto) { if (isEmpty(paperDto.getId())) { create(paperDto); } else { update(paperDto); } } public PaperDto findPaperById(Integer paperId) { return new PaperDto(findById(paperId)); } public Paper findById(Integer paperId) { return paperRepository.findById(paperId) .orElseThrow(() -> new EntityNotFoundException("Paper with id=" + paperId + " not found")); } public List findAllNotSelect(List paperIds) { if (!paperIds.isEmpty()) { return sortPapers(paperRepository.findByIdNotInAndConferencesIsNullAndStatusNot(paperIds, COMPLETED)); } else { return sortPapers(paperRepository.findByConferencesIsNullAndStatusNot(COMPLETED)); } } public List findAllNotCompleted() { return convert(paperRepository.findByStatusNot(COMPLETED), PaperDto::new); } public List findAllSelect(List paperIds) { return convert(paperRepository.findAllByIdIn(paperIds), PaperDto::new); } public List getPaperAuthors() { return userService.findAll(); } public List findAllCompletedByType(Paper.PaperType type) { return paperRepository.findByTypeAndStatus(type, Paper.PaperStatus.COMPLETED); } }