ng-tracker/src/main/java/ru/ulstu/grant/service/GrantService.java
2019-06-11 01:18:49 +04:00

352 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package ru.ulstu.grant.service;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.Errors;
import ru.ulstu.activity.service.ActivityService;
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.name.BaseService;
import ru.ulstu.paper.model.Paper;
import ru.ulstu.paper.model.PaperDto;
import ru.ulstu.paper.service.PaperService;
import ru.ulstu.ping.service.PingService;
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.text.ParseException;
import java.util.ArrayList;
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 java.util.stream.Collectors;
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 extends BaseService {
private final Logger log = LoggerFactory.getLogger(GrantService.class);
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;
private final KiasService kiasService;
private final PingService pingService;
private final ActivityService activityService;
public GrantService(GrantRepository grantRepository,
FileService fileService,
DeadlineService deadlineService,
ProjectService projectService,
UserService userService,
PaperService paperService,
EventService eventService,
GrantNotificationService grantNotificationService,
KiasService kiasService,
PingService pingService,
ActivityService activityService) {
this.grantRepository = grantRepository;
this.kiasService = kiasService;
this.baseRepository = grantRepository;
this.fileService = fileService;
this.deadlineService = deadlineService;
this.projectService = projectService;
this.userService = userService;
this.paperService = paperService;
this.eventService = eventService;
this.grantNotificationService = grantNotificationService;
this.pingService = pingService;
this.activityService = activityService;
}
public GrantDto getExistGrantById(Integer id) {
GrantDto grantDto = new GrantDto(findById(id));
return grantDto;
}
public List<Grant> findAll() {
return grantRepository.findAll();
}
public List<GrantDto> findAllDto() {
return convert(findAll(), GrantDto::new);
}
@Transactional
public Grant create(GrantDto grantDto) throws IOException {
Grant newGrant = copyFromDto(new Grant(), grantDto);
newGrant = grantRepository.save(newGrant);
eventService.createFromObject(newGrant, Collections.emptyList(), false, "гранта");
activityService.createActivity(new ArrayList<>(newGrant.getAuthors()), newGrant.getCommonActivityState());
grantNotificationService.sendCreateNotification(newGrant);
return newGrant;
}
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()));
if (!grant.getFiles().isEmpty()) {
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 = findById(grantDto.getId());
Set<User> oldAuthors = new HashSet<>(grant.getAuthors());
User oldLeader = grant.getLeader();
Grant.GrantStatus oldStatus = grant.getStatus();
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);
}
if(grant.getStatus() != oldStatus) {
activityService.createActivity(new ArrayList<>(grant.getAuthors()), grant.getCommonActivityState());
}
eventService.updateGrantDeadlines(grant);
return grant.getId();
}
@Transactional
public boolean delete(Integer grantId) throws IOException {
Grant grant = findById(grantId);
if (grant != null) {
grantRepository.delete(grant);
return true;
}
return false;
}
public List<Grant.GrantStatus> getGrantStatuses() {
return Arrays.asList(Grant.GrantStatus.values());
}
public boolean save(GrantDto grantDto, Errors errors) throws IOException {
grantDto.setName(grantDto.getTitle());
filterEmptyDeadlines(grantDto);
checkEmptyDeadlines(grantDto, errors);
checkEmptyLeader(grantDto, errors);
checkUniqueName(grantDto, errors, grantDto.getId(), "title", "Грант с таким именем уже существует");
if (errors.hasErrors()) {
return false;
}
if (isEmpty(grantDto.getId())) {
create(grantDto);
} else {
update(grantDto);
}
return true;
}
public boolean saveFromKias(GrantDto grantDto) throws IOException {
grantDto.setName(grantDto.getTitle());
String title = checkUniqueName(grantDto, grantDto.getId()); //проверка уникальности имени
if (title != null) {
Grant grantFromDB = grantRepository.findByTitle(title); //грант с таким же названием из бд
if (checkSameDeadline(grantDto, grantFromDB.getId())) { //если дедайны тоже совпадают
return false;
} else { //иначе грант уже был в системе, но в другом году, поэтому надо создать
create(grantDto);
return true;
}
} else { //иначе такого гранта ещё нет, поэтому надо создать
create(grantDto);
return true;
}
}
private void checkEmptyLeader(GrantDto grantDto, Errors errors) {
if (grantDto.getLeaderId().equals(-1)) {
errors.rejectValue("leaderId", "errorCode", "Укажите руководителя");
}
}
private void checkEmptyDeadlines(GrantDto grantDto, Errors errors) {
if (grantDto.getDeadlines().isEmpty()) {
errors.rejectValue("deadlines", "errorCode", "Не может быть пусто");
}
}
private boolean checkSameDeadline(GrantDto grantDto, Integer id) {
Date date = grantDto.getDeadlines().get(0).getDate(); //дата с сайта киас
Date foundGrantDate = deadlineService.findByGrantIdAndDate(id, date);
return foundGrantDate != null && foundGrantDate.compareTo(date) == 0;
}
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() {
return paperService.findAllNotCompleted();
}
public List<PaperDto> attachPaper(GrantDto grantDto) {
if (!grantDto.getPaperIds().isEmpty()) {
grantDto.getPapers().clear();
grantDto.setPapers(getGrantPapers(grantDto.getPaperIds()));
} else {
grantDto.getPapers().clear();
}
return grantDto.getPapers();
}
public GrantDto 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);
return grantDto;
}
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());
}
public List<Deadline> filterEmptyDeadlines(GrantDto grantDto) {
grantDto.setDeadlines(grantDto.getDeadlines().stream()
.filter(dto -> dto.getDate() != null || !StringUtils.isEmpty(dto.getDescription()))
.collect(Collectors.toList()));
return grantDto.getDeadlines();
}
@Transactional
public void createFromKias() throws IOException, ParseException {
for (GrantDto grantDto : kiasService.getNewGrantsDto()) {
if (saveFromKias(grantDto)) {
log.debug("GrantScheduler.loadGrantsFromKias new grant was loaded");
} else {
log.debug("GrantScheduler.loadGrantsFromKias grant wasn't loaded, cause it's already exists");
}
}
}
public List<GrantDto> findAllActiveDto() {
return convert(findAllActive(), GrantDto::new);
}
private List<Grant> findAllActive() {
return grantRepository.findAllActive();
}
public Grant findById(Integer id) {
return grantRepository.findOne(id);
}
@Transactional
public void ping(int grantId) throws IOException {
pingService.addPing(findById(grantId));
}
}