ng-tracker/src/main/java/ru/ulstu/grant/service/GrantService.java
2019-05-12 15:30:09 +04:00

265 lines
10 KiB
Java

package ru.ulstu.grant.service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.ulstu.deadline.model.Deadline;
import ru.ulstu.deadline.service.DeadlineService;
import ru.ulstu.file.model.FileDataDto;
import ru.ulstu.file.service.FileService;
import ru.ulstu.grant.model.Grant;
import ru.ulstu.grant.model.GrantDto;
import ru.ulstu.grant.repository.GrantRepository;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.service.PaperService;
import ru.ulstu.project.model.Project;
import ru.ulstu.project.model.ProjectDto;
import ru.ulstu.project.service.ProjectService;
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.Arrays;
import java.util.Collections;
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.springframework.util.ObjectUtils.isEmpty;
import static ru.ulstu.core.util.StreamApiUtils.convert;
import static ru.ulstu.grant.model.Grant.GrantStatus.APPLICATION;
@Service
public class GrantService {
private final static int MAX_DISPLAY_SIZE = 50;
private final GrantRepository grantRepository;
private final ProjectService projectService;
private final DeadlineService deadlineService;
private final FileService fileService;
private final UserService userService;
private final PaperService paperService;
private final EventService eventService;
private final GrantNotificationService grantNotificationService;
public GrantService(GrantRepository grantRepository,
FileService fileService,
DeadlineService deadlineService,
ProjectService projectService,
UserService userService,
PaperService paperService,
EventService eventService,
GrantNotificationService grantNotificationService) {
this.grantRepository = grantRepository;
this.fileService = fileService;
this.deadlineService = deadlineService;
this.projectService = projectService;
this.userService = userService;
this.paperService = paperService;
this.eventService = eventService;
this.grantNotificationService = grantNotificationService;
}
public List<Grant> findAll() {
return grantRepository.findAll();
}
public List<GrantDto> findAllDto() {
List<GrantDto> grants = convert(findAll(), GrantDto::new);
grants.forEach(grantDto -> grantDto.setTitle(StringUtils.abbreviate(grantDto.getTitle(), MAX_DISPLAY_SIZE)));
return grants;
}
public GrantDto findOneDto(Integer id) {
return new GrantDto(grantRepository.findOne(id));
}
@Transactional
public Integer create(GrantDto grantDto) throws IOException {
Grant newGrant = copyFromDto(new Grant(), grantDto);
newGrant = grantRepository.save(newGrant);
eventService.createFromGrant(newGrant);
grantNotificationService.sendCreateNotification(newGrant);
return newGrant.getId();
}
private Grant copyFromDto(Grant grant, GrantDto grantDto) throws IOException {
grant.setComment(grantDto.getComment());
grant.setStatus(grantDto.getStatus() == null ? APPLICATION : grantDto.getStatus());
grant.setTitle(grantDto.getTitle());
if (grantDto.getProject() != null && grantDto.getProject().getId() != null) {
grant.setProject(projectService.findById(grantDto.getProject().getId()));
}
grant.setDeadlines(deadlineService.saveOrCreate(grantDto.getDeadlines()));
grant.setFiles(fileService.saveOrCreate(grantDto.getFiles().stream()
.filter(f -> !f.isDeleted())
.collect(toList())));
grant.getAuthors().clear();
if (grantDto.getAuthorIds() != null && !grantDto.getAuthorIds().isEmpty()) {
grantDto.getAuthorIds().forEach(authorIds -> grant.getAuthors().add(userService.findById(authorIds)));
}
if (grantDto.getLeaderId() != null) {
grant.setLeader(userService.findById(grantDto.getLeaderId()));
}
grant.getPapers().clear();
if (grantDto.getPaperIds() != null && !grantDto.getPaperIds().isEmpty()) {
grantDto.getPaperIds().forEach(paperIds -> grant.getPapers().add(paperService.findPaperById(paperIds)));
}
return grant;
}
public void createProject(GrantDto grantDto) throws IOException {
grantDto.setProject(
new ProjectDto(projectService.save(new ProjectDto(grantDto.getTitle()))));
}
@Transactional
public Integer update(GrantDto grantDto) throws IOException {
Grant grant = grantRepository.findOne(grantDto.getId());
Set<User> oldAuthors = new HashSet<>(grant.getAuthors());
User oldLeader = grant.getLeader();
for (FileDataDto file : grantDto.getFiles().stream()
.filter(f -> f.isDeleted() && f.getId() != null)
.collect(toList())) {
fileService.delete(file.getId());
}
grantDto.getRemovedDeadlineIds().forEach(deadlineService::remove);
grantRepository.save(copyFromDto(grant, grantDto));
grant.getAuthors().forEach(author -> {
if (!oldAuthors.contains(author)) {
grantNotificationService.sendAuthorsChangeNotification(grant, oldAuthors);
}
});
oldAuthors.forEach(oldAuthor -> {
if (!grant.getAuthors().contains(oldAuthor)) {
grantNotificationService.sendAuthorsChangeNotification(grant, oldAuthors);
}
});
if (grant.getLeader() != oldLeader) {
grantNotificationService.sendLeaderChangeNotification(grant, oldLeader);
}
eventService.updateGrantDeadlines(grant);
return grant.getId();
}
@Transactional
public void delete(Integer grantId) throws IOException {
Grant grant = grantRepository.findOne(grantId);
grantRepository.delete(grant);
}
public List<Grant.GrantStatus> getGrantStatuses() {
return Arrays.asList(Grant.GrantStatus.values());
}
@Transactional
public Grant create(String title, Project projectId, Date deadlineDate, User user, Paper paper) {
Grant grant = new Grant();
grant.setTitle(title);
grant.setComment("Комментарий к гранту 1");
grant.setProject(projectId);
grant.setStatus(APPLICATION);
grant.getDeadlines().add(new Deadline(deadlineDate, "первый дедлайн"));
grant.getAuthors().add(user);
grant.setLeader(user);
grant.getPapers().add(paper);
grant = grantRepository.save(grant);
eventService.createFromGrant(grant);
grantNotificationService.sendCreateNotification(grant);
return grant;
}
public void save(GrantDto grantDto) throws IOException {
if (isEmpty(grantDto.getId())) {
create(grantDto);
} else {
update(grantDto);
}
}
public List<User> getGrantAuthors(GrantDto grantDto) {
List<User> filteredUsers = userService.filterByAgeAndDegree(grantDto.isHasAge(), grantDto.isHasDegree());
if (grantDto.isWasLeader()) {
filteredUsers = checkContains(filteredUsers, getCompletedGrantLeaders());
}
if (grantDto.isHasBAKPapers()) {
filteredUsers = checkContains(filteredUsers, getBAKAuthors());
}
if (grantDto.isHasScopusPapers()) {
filteredUsers = checkContains(filteredUsers, getScopusAuthors());
}
return filteredUsers;
}
private List<User> checkContains(List<User> filteredUsers, List<User> checkUsers) {
return filteredUsers.stream()
.filter(checkUsers::contains)
.collect(toList());
}
private List<User> getCompletedGrantLeaders() {
return grantRepository.findByStatus(Grant.GrantStatus.COMPLETED)
.stream()
.map(Grant::getLeader)
.collect(toList());
}
public List<PaperDto> getGrantPapers(List<Integer> paperIds) {
return paperService.findAllSelect(paperIds);
}
public List<PaperDto> getAllUncompletedPapers() {
List<PaperDto> papers = paperService.findAllNotCompleted();
papers.stream()
.forEach(paper ->
paper.setTitle(StringUtils.abbreviate(paper.getTitle(), MAX_DISPLAY_SIZE)));
return papers;
}
public void attachPaper(GrantDto grantDto) {
if (!grantDto.getPaperIds().isEmpty()) {
grantDto.getPapers().clear();
grantDto.setPapers(getGrantPapers(grantDto.getPaperIds()));
} else {
grantDto.getPapers().clear();
}
}
public void removeDeadline(GrantDto grantDto, Integer deadlineId) {
if (grantDto.getDeadlines().get(deadlineId).getId() != null) {
grantDto.getRemovedDeadlineIds().add(grantDto.getDeadlines().get(deadlineId).getId());
}
grantDto.getDeadlines().remove((int) deadlineId);
}
private List<User> getCompletedPapersAuthors(Paper.PaperType type) {
List<Paper> papers = paperService.findAllCompletedByType(type);
return papers.stream()
.filter(paper -> paper.getAuthors() != null)
.flatMap(paper -> paper.getAuthors().stream())
.collect(toList());
}
private List<User> getBAKAuthors() {
return getCompletedPapersAuthors(Paper.PaperType.VAK)
.stream()
.distinct()
.collect(toList());
}
private List<User> getScopusAuthors() {
List<User> authors = getCompletedPapersAuthors(Paper.PaperType.SCOPUS);
return authors
.stream()
.filter(author -> Collections.frequency(authors, author) > 3)
.collect(toList());
}
}