352 lines
14 KiB
Java
352 lines
14 KiB
Java
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));
|
||
}
|
||
}
|