/**
* Yona, 21st Century Project Hosting SW
*
* Copyright Yona & Yobi Authors & NAVER Corp. & NAVER LABS Corp.
* https://yona.io
**/
package models.support;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.Junction;
import controllers.AbstractPostingApp;
import controllers.UserApp;
import models.*;
import models.enumeration.State;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import play.data.format.Formats;
import javax.annotation.Nonnull;
import java.text.SimpleDateFormat;
import java.util.*;
public class SearchCondition extends AbstractPostingApp.SearchCondition implements Cloneable {
public String state;
public Boolean commentedCheck;
public Long milestoneId;
public Set labelIds = new HashSet<>();
public Long authorId;
public Long assigneeId;
public Project project;
public Long mentionId;
public Long sharerId;
public Long favoriteId;
public Organization organization;
public List projectNames;
public Long commenterId;
@Formats.DateTime(pattern = "yyyy-MM-dd")
public Date dueDate;
private User byUser = UserApp.currentUser();
/**
* This doesn't copy {@code pageNum}, because it is safe when changing tabs with page parameter.
*
* @return cloned instance of {@code SearchCondition}
*/
public SearchCondition clone() {
SearchCondition one = new SearchCondition();
one.orderBy = this.orderBy;
one.orderDir = this.orderDir;
one.filter = this.filter;
one.state = this.state;
one.commentedCheck = this.commentedCheck;
one.milestoneId = this.milestoneId;
one.labelIds = new HashSet<>(this.labelIds);
one.authorId = this.authorId;
one.assigneeId = this.assigneeId;
one.commenterId = this.commenterId;
one.mentionId = this.mentionId;
one.sharerId = this.sharerId;
one.favoriteId = this.favoriteId;
one.dueDate = this.dueDate;
one.projectNames = this.projectNames;
return one;
}
public SearchCondition setState(String state) {
this.state = state;
return this;
}
public SearchCondition setState(State state) {
this.state = state.state();
return this;
}
public SearchCondition setMilestoneId(Long milestoneId) {
this.milestoneId = milestoneId;
return this;
}
public SearchCondition setLabelIds(Set labelIds) {
this.labelIds = labelIds;
return this;
}
public SearchCondition setAuthorId(Long authorId) {
this.authorId = authorId;
return this;
}
public SearchCondition setAssigneeId(Long assigneeId) {
this.assigneeId = assigneeId;
return this;
}
public SearchCondition setCommenterId(Long commenterId) {
this.commenterId = commenterId;
return this;
}
public ExpressionList asExpressionList(@Nonnull Organization organization) {
ExpressionList el = Issue.finder.where();
if(isFilteredByProject()){
el.in("project.id", getFilteredProjectIds(organization));
} else {
el.in("project.id", getVisibleProjectIds(organization));
}
el.eq("isDraft", false);
setAssigneeIfExists(el);
setAuthorIfExist(el);
setMentionedIssuesIfExist(el);
setSharedIssuesIfExist(el);
setFavoriteIssuesIfExist(el);
setFilteredStringIfExist(el);
if (commentedCheck) {
el.ge("numOfComments", AbstractPosting.NUMBER_OF_ONE_MORE_COMMENTS);
}
setIssueState(el);
setOrderByIfExist(el);
if (dueDate != null) {
el.lt("dueDate", DateUtils.addDays(dueDate, 1));
}
return el;
}
private boolean isFilteredByProject() {
return CollectionUtils.isNotEmpty(this.projectNames);
}
private List getFilteredProjectIds(Organization organization) {
List projectIdsFilter = new ArrayList<>();
for(String projectName: projectNames){
for(Project project: organization.projects){
if(project.name.equalsIgnoreCase(projectName)
&& getVisibleProjectIds(organization).contains(project.id.toString())) {
projectIdsFilter.add(project.id);
break;
}
}
}
return projectIdsFilter;
}
private void setOrderByIfExist(ExpressionList el) {
if (StringUtils.isNotBlank(orderBy)) {
if (orderBy.equals("dueDate")) {
String formulaName = orderDir.equals("asc") ? "dueDateAsc" : "dueDateDesc";
el.orderBy("weight desc, isDraft desc, " + formulaName + " " + orderDir);
} else {
el.orderBy("weight desc, isDraft desc, " + orderBy + " " + orderDir);
}
}
}
private void setFilteredStringIfExist(ExpressionList el) {
if (StringUtils.isNotBlank(filter)) {
Junction junction = el.disjunction();
junction.icontains("title", filter)
.icontains("body", filter);
List