2019-07-20 13:03:14 +04:00

258 lines
10 KiB
Java

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<PaperListDto, Paper, PaperDto> {
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<User> 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<PaperDashboardDto> findAllActiveDto(int offset, int count) {
return convertPageable(findAllActive(offset, count), PaperDashboardDto::new);
}
public PageableItems<Paper> findAll(int offset, int count) {
final Page<Paper> 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<Paper> findAllActive(int offset, int count) {
Page<Paper> activePapersPage = paperRepository.findAllWithoutStatuses(new OffsetablePageRequest(offset, count), COMPLETED, FAILED);
return new PageableItems<>(activePapersPage.getTotalElements(), sortPapers(activePapersPage.getContent()));
}
@Override
protected List<Event> 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<PaperStatusDto> getPaperStatuses() {
return convert(Arrays.asList(Paper.PaperStatus.values()), PaperStatusDto::new);
}
public List<PaperTypeDto> 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<PaperListDto> filter(PaperFilterListDto filterDto) {
return convert(sortPapers(paperRepository.filter(
filterDto.getFilterAuthorId() == null ? null : userService.findById(filterDto.getFilterAuthorId()),
filterDto.getYear())), PaperListDto::new);
}
private List<Paper> sortPapers(List<Paper> 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<Paper> 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<Paper> findAllNotSelect(List<Integer> paperIds) {
if (!paperIds.isEmpty()) {
return sortPapers(paperRepository.findByIdNotInAndConferencesIsNullAndStatusNot(paperIds, COMPLETED));
} else {
return sortPapers(paperRepository.findByConferencesIsNullAndStatusNot(COMPLETED));
}
}
public List<PaperDto> findAllNotCompleted() {
return convert(paperRepository.findByStatusNot(COMPLETED), PaperDto::new);
}
public List<PaperDto> findAllSelect(List<Integer> paperIds) {
return convert(paperRepository.findAllByIdIn(paperIds), PaperDto::new);
}
public List<User> getPaperAuthors() {
return userService.findAll();
}
public List<Paper> findAllCompletedByType(Paper.PaperType type) {
return paperRepository.findByTypeAndStatus(type, Paper.PaperStatus.COMPLETED);
}
}