diff --git a/src/main/java/ru/ulstu/grant/model/Grant.java b/src/main/java/ru/ulstu/grant/model/Grant.java index abd61ac..d6f9f0c 100644 --- a/src/main/java/ru/ulstu/grant/model/Grant.java +++ b/src/main/java/ru/ulstu/grant/model/Grant.java @@ -1,5 +1,7 @@ package ru.ulstu.grant.model; +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; import org.hibernate.validator.constraints.NotBlank; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.UserContainer; @@ -66,10 +68,11 @@ public class Grant extends BaseEntity implements UserContainer { private String comment; - //Заявка на грант - @ManyToOne - @JoinColumn(name = "file_id") - private FileData application; + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "grant_id", unique = true) + @Fetch(FetchMode.SUBSELECT) + private List files = new ArrayList<>(); + @ManyToOne(cascade = CascadeType.ALL) @JoinColumn(name = "project_id") @@ -113,12 +116,12 @@ public class Grant extends BaseEntity implements UserContainer { this.comment = comment; } - public FileData getApplication() { - return application; + public List getFiles() { + return files; } - public void setApplication(FileData application) { - this.application = application; + public void setFiles(List files) { + this.files = files; } public String getTitle() { diff --git a/src/main/java/ru/ulstu/grant/model/GrantDto.java b/src/main/java/ru/ulstu/grant/model/GrantDto.java index 3fb77c5..e842b10 100644 --- a/src/main/java/ru/ulstu/grant/model/GrantDto.java +++ b/src/main/java/ru/ulstu/grant/model/GrantDto.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang3.StringUtils; import org.hibernate.validator.constraints.NotEmpty; import ru.ulstu.deadline.model.Deadline; +import ru.ulstu.file.model.FileDataDto; import ru.ulstu.paper.model.Paper; import ru.ulstu.project.model.ProjectDto; import ru.ulstu.user.model.UserDto; @@ -25,7 +26,7 @@ public class GrantDto { private Grant.GrantStatus status; private List deadlines = new ArrayList<>(); private String comment; - private String applicationFileName; + private List files = new ArrayList<>(); private ProjectDto project; private Set authorIds; private Set authors; @@ -33,6 +34,8 @@ public class GrantDto { private boolean wasLeader; private boolean hasAge; private boolean hasDegree; + private boolean hasBAKPapers; + private boolean hasScopusPapers; private List paperIds = new ArrayList<>(); private List papers = new ArrayList<>(); private List removedDeadlineIds = new ArrayList<>(); @@ -47,6 +50,7 @@ public class GrantDto { @JsonProperty("status") Grant.GrantStatus status, @JsonProperty("deadlines") List deadlines, @JsonProperty("comment") String comment, + @JsonProperty("files") List files, @JsonProperty("project") ProjectDto project, @JsonProperty("authorIds") Set authorIds, @JsonProperty("authors") Set authors, @@ -61,8 +65,9 @@ public class GrantDto { this.status = status; this.deadlines = deadlines; this.comment = comment; - this.applicationFileName = null; + this.files = files; this.project = project; + this.authorIds = authorIds; this.authors = authors; this.leaderId = leaderId; this.wasLeader = wasLeader; @@ -78,8 +83,8 @@ public class GrantDto { this.status = grant.getStatus(); this.deadlines = grant.getDeadlines(); this.comment = grant.getComment(); + this.files = convert(grant.getFiles(), FileDataDto::new); this.project = grant.getProject() == null ? null : new ProjectDto(grant.getProject()); - this.applicationFileName = grant.getApplication() == null ? null : grant.getApplication().getName(); this.authorIds = convert(grant.getAuthors(), user -> user.getId()); this.authors = convert(grant.getAuthors(), UserDto::new); this.leaderId = grant.getLeader().getId(); @@ -130,6 +135,14 @@ public class GrantDto { this.comment = comment; } + public List getFiles() { + return files; + } + + public void setFiles(List files) { + this.files = files; + } + public ProjectDto getProject() { return project; } @@ -138,14 +151,6 @@ public class GrantDto { this.project = project; } - public String getApplicationFileName() { - return applicationFileName; - } - - public void setApplicationFileName(String applicationFileName) { - this.applicationFileName = applicationFileName; - } - public Set getAuthorIds() { return authorIds; } @@ -224,4 +229,20 @@ public class GrantDto { public void setRemovedDeadlineIds(List removedDeadlineIds) { this.removedDeadlineIds = removedDeadlineIds; } + + public boolean isHasBAKPapers() { + return hasBAKPapers; + } + + public void setHasBAKPapers(boolean hasBAKPapers) { + this.hasBAKPapers = hasBAKPapers; + } + + public boolean isHasScopusPapers() { + return hasScopusPapers; + } + + public void setHasScopusPapers(boolean hasScopusPapers) { + this.hasScopusPapers = hasScopusPapers; + } } diff --git a/src/main/java/ru/ulstu/grant/service/GrantService.java b/src/main/java/ru/ulstu/grant/service/GrantService.java index cabed80..cb86b7a 100644 --- a/src/main/java/ru/ulstu/grant/service/GrantService.java +++ b/src/main/java/ru/ulstu/grant/service/GrantService.java @@ -5,6 +5,7 @@ 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; @@ -19,10 +20,11 @@ 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.List; -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; @@ -81,9 +83,9 @@ public class GrantService { grant.setProject(projectService.findById(grantDto.getProject().getId())); } grant.setDeadlines(deadlineService.saveOrCreate(grantDto.getDeadlines())); - if (grantDto.getApplicationFileName() != null) { - grant.setApplication(fileService.createFileFromTmp(grantDto.getApplicationFileName())); - } + 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))); @@ -106,8 +108,10 @@ public class GrantService { @Transactional public Integer update(GrantDto grantDto) throws IOException { Grant grant = grantRepository.findOne(grantDto.getId()); - if (grantDto.getApplicationFileName() != null && grant.getApplication() != null) { - fileService.deleteFile(grant.getApplication()); + 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)); @@ -117,9 +121,6 @@ public class GrantService { @Transactional public void delete(Integer grantId) throws IOException { Grant grant = grantRepository.findOne(grantId); - if (grant.getApplication() != null) { - fileService.deleteFile(grant.getApplication()); - } grantRepository.delete(grant); } @@ -153,19 +154,28 @@ public class GrantService { public List getGrantAuthors(GrantDto grantDto) { List filteredUsers = userService.filterByAgeAndDegree(grantDto.isHasAge(), grantDto.isHasDegree()); if (grantDto.isWasLeader()) { - filteredUsers = filteredUsers - .stream() - .filter(getCompletedGrantLeaders()::contains) - .collect(Collectors.toList()); + filteredUsers = checkContains(filteredUsers, getCompletedGrantLeaders()); + } + if (grantDto.isHasBAKPapers()) { + filteredUsers = checkContains(filteredUsers, getBAKAuthors()); + } + if (grantDto.isHasScopusPapers()) { + filteredUsers = checkContains(filteredUsers, getScopusAuthors()); } return filteredUsers; } + private List checkContains(List filteredUsers, List checkUsers) { + return filteredUsers.stream() + .filter(checkUsers::contains) + .collect(toList()); + } + private List getCompletedGrantLeaders() { return grantRepository.findByStatus(Grant.GrantStatus.COMPLETED) .stream() .map(Grant::getLeader) - .collect(Collectors.toList()); + .collect(toList()); } public List getGrantPapers(List paperIds) { @@ -193,4 +203,27 @@ public class GrantService { grantDto.getDeadlines().remove((int) deadlineId); } + private List getCompletedPapersAuthors(Paper.PaperType type) { + List papers = paperService.findAllCompletedByType(type); + return papers.stream() + .filter(paper -> paper.getAuthors() != null) + .flatMap(paper -> paper.getAuthors().stream()) + .collect(toList()); + + } + + private List getBAKAuthors() { + return getCompletedPapersAuthors(Paper.PaperType.VAK) + .stream() + .distinct() + .collect(toList()); + } + + private List getScopusAuthors() { + List authors = getCompletedPapersAuthors(Paper.PaperType.SCOPUS); + return authors + .stream() + .filter(author -> Collections.frequency(authors, author) > 3) + .collect(toList()); + } } diff --git a/src/main/java/ru/ulstu/paper/repository/PaperRepository.java b/src/main/java/ru/ulstu/paper/repository/PaperRepository.java index cab9b1a..f935247 100644 --- a/src/main/java/ru/ulstu/paper/repository/PaperRepository.java +++ b/src/main/java/ru/ulstu/paper/repository/PaperRepository.java @@ -16,4 +16,6 @@ public interface PaperRepository extends JpaRepository { List findByIdNotIn(List paperIds); List findAllByIdIn(List paperIds); + + List findByTypeAndStatus(Paper.PaperType type, Paper.PaperStatus status); } diff --git a/src/main/java/ru/ulstu/paper/service/PaperService.java b/src/main/java/ru/ulstu/paper/service/PaperService.java index 3db7c84..f98997d 100644 --- a/src/main/java/ru/ulstu/paper/service/PaperService.java +++ b/src/main/java/ru/ulstu/paper/service/PaperService.java @@ -303,4 +303,8 @@ public class PaperService { StringUtils.isEmpty(referenceDto.getPublisher()) ? "" : referenceDto.getPublisher() + ", ", referenceDto.getPages()); } + + public List findAllCompletedByType(Paper.PaperType type) { + return paperRepository.findByTypeAndStatus(type, Paper.PaperStatus.COMPLETED); + } } diff --git a/src/main/resources/db/changelog-20190430_000000-schema.xml b/src/main/resources/db/changelog-20190430_000000-schema.xml new file mode 100644 index 0000000..58a3bc5 --- /dev/null +++ b/src/main/resources/db/changelog-20190430_000000-schema.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index 6f8e878..3cc05ae 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -36,4 +36,5 @@ + \ No newline at end of file diff --git a/src/main/resources/public/css/grant.css b/src/main/resources/public/css/grant.css index 3c0cfc8..2e6349d 100644 --- a/src/main/resources/public/css/grant.css +++ b/src/main/resources/public/css/grant.css @@ -28,4 +28,16 @@ .btn-delete-deadline { color: black; +} + +.div-file-name{ + padding-top: 6px; +} + +.div-loader { + margin-bottom: 5px; +} + +.div-row-file { + margin-bottom: 2px; } \ No newline at end of file diff --git a/src/main/resources/templates/grants/fragments/grantFilesListFragment.html b/src/main/resources/templates/grants/fragments/grantFilesListFragment.html new file mode 100644 index 0000000..2547c80 --- /dev/null +++ b/src/main/resources/templates/grants/fragments/grantFilesListFragment.html @@ -0,0 +1,37 @@ + + + + + + +
+ + +
+ + + + +
+ + +
+
+ + + +
+
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/grants/grant.html b/src/main/resources/templates/grants/grant.html index 9c0736d..4d3cdde 100644 --- a/src/main/resources/templates/grants/grant.html +++ b/src/main/resources/templates/grants/grant.html @@ -61,7 +61,7 @@
-
- +
+
-
+
+
+
-
@@ -111,14 +114,16 @@
- +
- +
@@ -233,20 +238,100 @@ new FileLoader({ div: "loader", url: urlFileUpload, - maxSize: 1.5, - extensions: ["doc", "docx", "xls", "jpg", "pdf", "txt", "png"], + maxSize: -1, + extensions: [], callback: function (response) { showFeedbackMessage("Файл успешно загружен"); console.debug(response); + addNewFile(response); } }); $('.selectpicker').selectpicker(); }); /*]]>*/ + function addNewFile(fileDto) { + var fileNumber = $("#files-list div.row").length; + var newFileRow = $("
") + .attr("id", 'files' + fileNumber) + .addClass("row div-row-file"); + var idInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".id") + .attr("value", '') + .attr("name", "files[" + fileNumber + "].id"); + newFileRow.append(idInput); + var flagInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".deleted") + .attr("value", "false") + .attr("name", "files[" + fileNumber + "].deleted"); + newFileRow.append(flagInput); + var nameInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".name") + .attr("value", fileDto.fileName) + .attr("name", "files[" + fileNumber + "].name"); + newFileRow.append(nameInput); + + var tmpFileNameInput = $("") + .attr("type", "hidden") + .attr("id", "files" + fileNumber + ".tmpFileName") + .attr("value", fileDto.tmpFileName) + .attr("name", "files[" + fileNumber + "].tmpFileName"); + newFileRow.append(tmpFileNameInput); + + var nameDiv = $("
") + .addClass("col-10 div-file-name") + .append($("").text(fileDto.fileName) + .attr("href", 'javascript:void(0)') + .attr("onclick", "downloadFile('" + fileDto.tmpFileName + "',null,'" + fileDto.fileName + "')")); + newFileRow.append(nameDiv); + + var nextDiv = $("
") + .addClass("col-2"); + + var nextA = $("") + .addClass("btn btn-danger float-right") + .attr("onclick", "$('#files" + fileNumber + "\\\\.deleted').val('true'); $('#files" + fileNumber + "').hide();") + .append(($("").attr("aria-hidden", "true")).append($("").addClass("fa fa-times"))) + ; + nextDiv.append(nextA) + newFileRow.append(nextDiv); + $("#files-list").append(newFileRow); + } + + function downloadFile(tmpName, fileId, downloadName) { + let xhr = new XMLHttpRequest(); + if (fileId != null) xhr.open('GET', urlFileDownload + fileId); + if (tmpName != null) xhr.open('GET', urlFileDownloadTmp + tmpName); + xhr.responseType = 'blob'; + + var formData = new FormData(); + if (fileId != null) formData.append("file-id", fileId); + if (tmpName != null) formData.append("tmp-file-name", tmpName); + + xhr.send(formData); + + xhr.onload = function () { + if (this.status == 200) { + console.debug(this.response); + var blob = new Blob([this.response], {type: '*'}); + let a = document.createElement("a"); + a.style = "display: none"; + document.body.appendChild(a); + let url = window.URL.createObjectURL(blob); + a.href = url; + a.download = downloadName; + a.click(); + window.URL.revokeObjectURL(url); + } else { + } + } + } - -