package ru.ulstu.paper.model; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; import jakarta.persistence.OneToMany; import jakarta.persistence.OrderBy; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; import jakarta.validation.constraints.NotBlank; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import ru.ulstu.conference.model.Conference; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.EventSource; import ru.ulstu.core.model.UserActivity; import ru.ulstu.deadline.model.Deadline; import ru.ulstu.file.model.FileData; import ru.ulstu.grant.model.Grant; import ru.ulstu.timeline.model.Event; import ru.ulstu.user.model.User; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.Set; @Entity @DiscriminatorValue("PAPER") public class Paper extends BaseEntity implements UserActivity, EventSource { public enum PaperStatus { ATTENTION("Обратить внимание", "text-warning"), ON_PREPARATION("На подготовке", "text-primary"), ON_REVIEW("Отправлена на проверку", "text-review"), ACCEPTED("Принята", "text-accepted"), NOT_ACCEPTED("Не принята", "text-not-accepted"), COMPLETED("Завершена (опубликована)", "text-success"), DRAFT("Черновик", "text-draft"), FAILED("Провалены сроки", "text-failed"); private final String statusName; private final String elementClass; PaperStatus(String name, String elementClass) { this.statusName = name; this.elementClass = elementClass; } public String getStatusName() { return statusName; } public String getElementClass() { return elementClass; } } public enum PaperType { OTHER("Прочая публикация"), VAK("ВАК"), SCOPUS("Scopus"), WEB_OF_SCIENCE("Web Of Science"); private final String typeName; PaperType(String name) { this.typeName = name; } public String getTypeName() { return typeName; } } @NotBlank private String title; @Enumerated(value = EnumType.STRING) private PaperStatus status = PaperStatus.DRAFT; @Enumerated(value = EnumType.STRING) private PaperType type = PaperType.OTHER; @Column(name = "create_date") @Temporal(TemporalType.TIMESTAMP) private Date createDate = new Date(); @Column(name = "update_date") @Temporal(TemporalType.TIMESTAMP) private Date updateDate = new Date(); @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "paper_id", unique = true) @Fetch(FetchMode.SUBSELECT) @OrderBy("date") private List deadlines = new ArrayList<>(); private String comment; private String url; private Boolean locked = false; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "paper_id") private List events = new ArrayList<>(); @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "paper_id", unique = true) @Fetch(FetchMode.SUBSELECT) private List files = new ArrayList<>(); @ManyToMany(fetch = FetchType.EAGER) private Set authors = new HashSet<>(); @ManyToOne() @JoinColumn(name = "conference_id") private Conference conference; @ManyToMany(mappedBy = "papers") private List grants; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "paper_id", unique = true) @Fetch(FetchMode.SUBSELECT) private List references = new ArrayList<>(); public PaperStatus getStatus() { return status; } public void setStatus(PaperStatus status) { this.status = status; } public PaperType getType() { return type; } public void setType(PaperType type) { this.type = type; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public Date getUpdateDate() { return updateDate; } public void setUpdateDate(Date updateDate) { this.updateDate = updateDate; } public List getDeadlines() { return deadlines; } public void setDeadlines(List deadlines) { this.deadlines = deadlines; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } public Boolean getLocked() { return locked; } public void setLocked(Boolean locked) { this.locked = locked; } public List getFiles() { return files; } public void setFiles(List files) { this.files = files; } public String getTitle() { return title; } @Override public List getRecipients() { return new ArrayList<>(authors); } @Override public void addObjectToEvent(Event event) { event.setPaper(this); } public void setTitle(String title) { this.title = title; } public Set getAuthors() { return authors; } public void setAuthors(Set authors) { this.authors = authors; } public List getEvents() { return events; } public void setEvents(List events) { this.events = events; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public Conference getConference() { return conference; } public void setConference(Conference conference) { this.conference = conference; } public List getGrants() { return grants; } public void setGrants(List grants) { this.grants = grants; } @Override public Set getActivityUsers() { return getAuthors(); } public List getReferences() { return references; } public void setReferences(List references) { this.references = references; } public Optional getNextDeadline() { return deadlines .stream() .filter(deadline -> deadline.getDate() != null) .sorted(Comparator.comparing(Deadline::getDate)) .filter(d -> d.getDate().after(new Date())) .findFirst(); } public boolean lastDeadlineFailed() { return !deadlines .stream() .filter(deadline -> deadline.getDate() != null) .filter(d -> d.getDate().after(new Date())) .findAny() .isPresent(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } if (!super.equals(o)) { return false; } Paper paper = (Paper) o; return Objects.equals(title, paper.title) && status == paper.status && type == paper.type && Objects.equals(deadlines, paper.deadlines) && Objects.equals(comment, paper.comment) && Objects.equals(url, paper.url) && Objects.equals(locked, paper.locked) && Objects.equals(events, paper.events) && Objects.equals(files, paper.files) && Objects.equals(authors, paper.authors) && Objects.equals(conference, paper.conference) && Objects.equals(grants, paper.grants); } @Override public int hashCode() { return Objects.hash(super.hashCode(), title, status, type, createDate, updateDate, deadlines, comment, url, locked, events, files, authors, conference, grants); } }