added new idea status inactive and worker thread that checks for ideas that does not have filled Watson boxes before application period end date, and if not, inactivates the idea

This commit is contained in:
Emil Siverhall 2012-09-10 09:37:06 +02:00
parent 269e979891
commit dd47bde884
9 changed files with 539 additions and 454 deletions

@ -31,7 +31,9 @@ public class IdeaStatusColumnPanel extends Panel {
add(new Label("label", "Matched, course starting "+new DateFormatter().createFormattedString(idea.getApplicationPeriod().getCourseStartDate())));
else if (idea.getIdeaStatus().equals(IdeaStatus.COMPLETED)&&idea.getProject()!=null)
add(new Label("label", "Matched, project created"));
else
else if (idea.getIdeaStatus().equals(IdeaStatus.INACTIVE))
add(new Label("label", "Inactivated"));
else
add(new Label("label", "Matched, waiting for project creation"));
}

@ -54,8 +54,9 @@ public abstract class Idea extends DomainObject {
*
* WAITING: Idea created by supervisor, waiting to be taken by authors
* TAKEN: Waiting idea that's been taken by author(s)
* AUTHOR_CREATED: Idea submitted by author, waiting for supervisor
* COMPLETED: Taken ideas where application period has ended. Completed + project!=null means a project has been created.
* INACTIVE: Ideas that's been matched but by some reason shouldn't turn into projects is inactivated.
* Example: Watson boxes haven't been filled in before application period end date.
*
*/
public static enum IdeaStatus {
@ -74,9 +75,9 @@ public abstract class Idea extends DomainObject {
return "Completed";
}
},
AUTHOR_CREATED {
INACTIVE {
public String toString() {
return "Author created";
return "Inactivated";
}
}

@ -9,6 +9,7 @@ import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.util.DateFormatter;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
@ -58,6 +59,7 @@ public class CompleteIdeaDialogPanel extends Panel {
}
};
button.add(new JavascriptEventConfirmation("onClick", "Are you sure you want to save your changes?"));
button.setVisible(!model.getObject().getIdeaStatus().equals(IdeaStatus.INACTIVE));
add(button);
}

@ -20,7 +20,6 @@ import org.odlabs.wiquery.ui.dialog.Dialog;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.datatables.AjaxLinkColumn;
import se.su.dsv.scipro.datatables.ClickableTitleColumn;
import se.su.dsv.scipro.datatables.DateColumn;
import se.su.dsv.scipro.datatables.GenericDataPanel;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
@ -136,6 +135,8 @@ public class MySupervisorIdeasPanel extends Panel {
item.add(new Label(componentId, "Matched, course starting "+new DateFormatter().createFormattedString(idea.getApplicationPeriod().getCourseStartDate())));
}
}
if(idea.getIdeaStatus().equals(IdeaStatus.INACTIVE))
item.add(new Label(componentId, "Inactivated"));
if(idea.getIdeaStatus().equals(IdeaStatus.COMPLETED)&&idea.getProject()!=null)
item.add(new Label(componentId, "Matched, project created"));

@ -18,7 +18,11 @@ import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.*;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
@ -27,7 +31,6 @@ import se.su.dsv.scipro.match.dataobject.QSupervisorIdea;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.dataobject.Watson;
import se.su.dsv.scipro.peer.data.dao.controllers.Pair;
import se.su.dsv.scipro.peer.data.dataobjects.QPeerReview;
import se.su.dsv.scipro.springdata.repos.SupervisorIdeaRepo;
import se.su.dsv.scipro.springdata.services.ApplicationPeriodService;
import se.su.dsv.scipro.springdata.services.FirstMeetingService;
@ -99,112 +102,6 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
}
@Override
@Transactional(readOnly = false)
public void deleteWaitingIdea(SupervisorIdea idea) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if (!reloadedIdea.getIdeaStatus().equals(IdeaStatus.WAITING)) //Should not be deleted if IdeaStatus is anything else than waiting.
return;
else
supervisorIdeaRepo.delete(reloadedIdea);
}
@Override
@Transactional(readOnly = false)
public void acceptIdea(SupervisorIdea idea, User mainAuthor,
SortedSet<Student> studentSet) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
Student author = studentService.findByUser(mainAuthor);
for (Student s : studentSet) {
s = studentService.findOne(s.getId()); //Needed for lazy loading to work.
IdeaParticipation ip = new IdeaParticipation();
ip.setStudent(s);
ip.setSupervisorIdea(reloadedIdea);
ip.setDateCreated(new Date());
ip.setConfirmed(false);
s.addIdeaParticipation(ip);
}
IdeaParticipation mainParticipation = new IdeaParticipation();
mainParticipation.setStudent(author);
mainParticipation.setSupervisorIdea(reloadedIdea);
mainParticipation.setDateCreated(new Date());
mainParticipation.setConfirmed(true);
author.addIdeaParticipation(mainParticipation);
reloadedIdea.setIdeaStatus(IdeaStatus.TAKEN);
reloadedIdea.setApplicationPeriod(applicationPeriodService.getCurrentPeriod(new Date(), reloadedIdea.getProjectClass()));
}
@Override
@Transactional(readOnly = false)
public void changeSupervisor(SupervisorIdea idea, Employee newSupervisor) {
SupervisorIdea reloadedIdea = findOne(idea.getId());
reloadedIdea.setCreator(newSupervisor);
save(reloadedIdea);
}
@Override
@Transactional(readOnly = false)
public void removeAuthor(SupervisorIdea idea, Student author) {
SupervisorIdea reloadedIdea = findOne(idea.getId());
Student reloadedAuthor = studentService.findOne(author.getId());
for (IdeaParticipation ip : reloadedIdea.getIdeaParticipations()) {
if (ip.getStudent().equals(reloadedAuthor))
reloadedAuthor.removeIdeaParticipation(ip);
}
}
@Override
public Pair<Boolean, String> validateIdeaAcceptance(SupervisorIdea idea,
User mainAuthor, SortedSet<Student> students) {
if (students.size() > MAX_PARTNERS) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: More than " + MAX_PARTNERS + " partner(s) added to project idea.");
return new Pair<Boolean, String>(false, "You may not add more than " + MAX_PARTNERS + " partner to the project idea"); //You may not add more than a specified number of partners.
}
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if (reloadedIdea.getProjectClass().getCode().equals(ProjectClass.BACHELOR) && students.isEmpty()) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: No partner selected on bachelor level thesis.");
return new Pair<Boolean, String>(false, "You need to select a partner when the idea is on bachelor level"); //You need to select a partner if the idea is on bachelor level.
}
Student author = studentService.findByUser(mainAuthor);
if (students.contains(author)) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: Accepting user selected as his/her own partner.");
return new Pair<Boolean, String>(false, "You may not select yourself as partner"); //You may not select yourself as partner.
}
if (authorParticipatingOnIdea(author)) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: Author already attached to a taken project idea.");
return new Pair<Boolean, String>(false, "You may only be part of one project idea."); //You may only be part of one taken idea at once.
}
for (Student s : students) {
if (authorParticipatingOnIdea(s)) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: Co-author already attached to a taken project idea.");
return new Pair<Boolean, String>(false, "Your project partner is already part of another project idea");
}
}
return new Pair<Boolean, String>(true, "Validation successful");
}
@Override
public Pair<Boolean, String> validatePartnerAcceptance(User user) {
Student author = studentService.findByUser(user);
if (partnerAlreadyParticipatingOnIdea(author)) {
logger.error("Accepting user: " + user.getEmailAddress() + " Error: May not accept to be a partner if already participating in another idea.");
return new Pair<Boolean, String>(false, "You may not accept to be a partner if already participating in another idea");
}
return new Pair<Boolean, String>(true, "Validation passed");
}
@Override
public Pair<Boolean, String> validateSupervisorIdeaSubmission(SupervisorIdea idea, SortedSet<Student> students, ResearchArea researchArea, Set<Keyword> keywords) {
@ -233,163 +130,284 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
}
@Override
@Transactional(readOnly = false)
public void partnerAcceptIdea(SupervisorIdea idea, User loggedInUser) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
Student author = studentService.findByUser(loggedInUser);
for (IdeaParticipation ip : reloadedIdea.getIdeaParticipations()) {
if (ip.getStudent().equals(author))
ip.setConfirmed(true);
}
if (reloadedIdea.getApplicationPeriod() == null) {
reloadedIdea.setApplicationPeriod(applicationPeriodService.getCurrentPeriod(new Date(), reloadedIdea.getProjectClass()));
}
}
@Override
@Transactional(readOnly = false)
public void declineIdea(SupervisorIdea idea) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
//Remove participations
for (IdeaParticipation ip : reloadedIdea.getIdeaParticipations()) {
Student s = ip.getStudent();
s.removeIdeaParticipation(ip);
}
//Remove first meeting info if existing
if (reloadedIdea.getFirstMeeting() != null)
firstMeetingService.delete(reloadedIdea.getFirstMeeting().getId());
reloadedIdea.setFirstMeeting(null);
//Erase watson boxes
reloadedIdea.setWatson(new Watson());
//Remove application period association
reloadedIdea.setApplicationPeriod(null);
//Change status back to waiting
reloadedIdea.setIdeaStatus(IdeaStatus.WAITING);
}
@Override
@Transactional ( readOnly = false )
public void deleteWaitingIdea(SupervisorIdea idea) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if(!reloadedIdea.getIdeaStatus().equals(IdeaStatus.WAITING)) //Should not be deleted if IdeaStatus is anything else than waiting.
return;
else
supervisorIdeaRepo.delete(reloadedIdea);
}
@Override
@Transactional ( readOnly = false )
public void acceptIdea(SupervisorIdea idea, User mainAuthor,
SortedSet<Student> studentSet) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
Student author = studentService.findByUser(mainAuthor);
for(Student s : studentSet) {
s = studentService.findOne(s.getId()); //Needed for lazy loading to work.
IdeaParticipation ip = new IdeaParticipation();
ip.setStudent(s);
ip.setSupervisorIdea(reloadedIdea);
ip.setDateCreated(new Date());
ip.setConfirmed(false);
s.addIdeaParticipation(ip);
}
IdeaParticipation mainParticipation = new IdeaParticipation();
mainParticipation.setStudent(author);
mainParticipation.setSupervisorIdea(reloadedIdea);
mainParticipation.setDateCreated(new Date());
mainParticipation.setConfirmed(true);
author.addIdeaParticipation(mainParticipation);
reloadedIdea.setIdeaStatus(IdeaStatus.TAKEN);
reloadedIdea.setApplicationPeriod(applicationPeriodService.getCurrentPeriod(new Date(), reloadedIdea.getProjectClass()));
}
@Override
@Transactional(readOnly = false)
public void updateIdea(SupervisorIdea idea) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if (idea.getWatson().getWhat() != null)
reloadedIdea.getWatson().setWhat(idea.getWatson().getWhat());
if (idea.getWatson().getWhy() != null)
reloadedIdea.getWatson().setWhy(idea.getWatson().getWhy());
if (idea.getWatson().getTheoryHow() != null)
reloadedIdea.getWatson().setTheoryHow(idea.getWatson().getTheoryHow());
if (idea.getWatson().getPracticalHow() != null)
reloadedIdea.getWatson().setPracticalHow(idea.getWatson().getPracticalHow());
}
@Override
public void checkForExpiredParticipation(SupervisorIdea idea, int confirmationDays) {
Date expirationDate = new DateTime().minusDays(confirmationDays).toDate();
for (IdeaParticipation ip : idea.getIdeaParticipations()) {
if (!ip.isConfirmed() && ip.getDateCreated().compareTo(expirationDate) < 0) {
logger.info(ip.getStudent() + " did not confirm participation on idea: " + idea.getTitle() + ". Removing participants from the idea");
declineIdea(idea);
}
}
}
@Override
@Transactional(readOnly = false)
public SupervisorIdea saveMeeting(SupervisorIdea idea, Date date, String desc) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if (reloadedIdea.getFirstMeeting() != null) {
reloadedIdea.getFirstMeeting().setFirstMeetingDate(date);
reloadedIdea.getFirstMeeting().setDescription(desc);
} else {
FirstMeeting meeting = new FirstMeeting(date, desc, reloadedIdea);
meeting = firstMeetingService.save(meeting);
reloadedIdea.setFirstMeeting(meeting);
}
return reloadedIdea;
}
@Override
@Transactional
public boolean hasTakenIdeas(User authorUser, boolean confirmed) {
Student author = studentService.findByUser(authorUser);
// find unconfirmed ideas by author
List<SupervisorIdea> ideas = findIdeas(IdeaStatus.TAKEN, author, confirmed);
if (!ideas.isEmpty())
return true;
else
return false;
}
@Override
public boolean hasUnconfirmedAuthor(SupervisorIdea idea) {
Set<IdeaParticipation> ipList = idea.getIdeaParticipations();
for (IdeaParticipation ip : ipList) {
if (!ip.isConfirmed()) {
return true;
}
}
return false;
}
@Override
public boolean hasUnfinishedWatson(SupervisorIdea idea) {
Watson watson = idea.getWatson();
return watson.getWhat().equals("") || watson.getWhy().equals("") || watson.getPracticalHow().equals("") || watson.getTheoryHow().equals("");
}
// Only editable if idea status is waiting and the current user is the creator
@Override
public boolean isIdeaEditable(SupervisorIdea idea, User currentUser) {
return idea.getIdeaStatus().equals(IdeaStatus.WAITING) && idea.getCreator().getUser().equals(currentUser);
}
@Override
public boolean isAdminDeletable(SupervisorIdea idea) {
return idea.getIdeaStatus().equals(IdeaStatus.WAITING);
}
@Override
public Page<SupervisorIdea> findAll(FilterParams params, Pageable pageable) {
if (params != null)
return supervisorIdeaRepo.findAll(fromParams(params), pageable);
else
return supervisorIdeaRepo.findAll(pageable);
}
@Override
public Page<SupervisorIdea> findByStatus(IdeaStatus status, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status), pageable);
}
@Override
public Page<SupervisorIdea> findByStatusAndParams(IdeaStatus status, FilterParams params, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status).and(predicateFromParams(params)), pageable);
}
@Override
public Page<SupervisorIdea> findByStatusAndCapabilities(IdeaStatus status, FilterParams params, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status).and(capabilityFilter(params.getLevels())), pageable);
}
@Override
public Page<SupervisorIdea> findIdeasWithoutProjects(Employee supervisor, Pageable pageable) {
return supervisorIdeaRepo.findAll(bySupervisor(supervisor).and(projectCreated(false)).and(byStatus(IdeaStatus.TAKEN).or(byStatus(IdeaStatus.COMPLETED))), pageable);
}
@Override
public List<SupervisorIdea> findByStatusAndAuthor(IdeaStatus status, Student author) {
List<SupervisorIdea> ideas = supervisorIdeaRepo.findIdeasByAuthorAndStatus(author, status);
return ideas;
}
@Override
public List<SupervisorIdea> findIdeas(IdeaStatus status, Student author, boolean confirmed) {
List<SupervisorIdea> ideas = supervisorIdeaRepo.findIdeas(author, status, confirmed);
return ideas;
}
@Override
@Transactional(readOnly=false)
public void changeSupervisor(SupervisorIdea idea, Employee newSupervisor) {
SupervisorIdea reloadedIdea = findOne(idea.getId());
reloadedIdea.setCreator(newSupervisor);
save(reloadedIdea);
}
@Override
@Transactional(readOnly=false)
public void removeAuthor(SupervisorIdea idea, Student author) {
SupervisorIdea reloadedIdea = findOne(idea.getId());
Student reloadedAuthor = studentService.findOne(author.getId());
for(IdeaParticipation ip : reloadedIdea.getIdeaParticipations()){
if(ip.getStudent().equals(reloadedAuthor))
reloadedAuthor.removeIdeaParticipation(ip);
}
}
@Override
@Transactional(readOnly=false)
public void inactivateIdea(SupervisorIdea idea) {
SupervisorIdea reloadedIdea = findOne(idea.getId());
reloadedIdea.setIdeaStatus(IdeaStatus.INACTIVE);
}
@Override
public Pair<Boolean, String> validateIdeaAcceptance(SupervisorIdea idea,
User mainAuthor, SortedSet<Student> students) {
if(students.size()> MAX_PARTNERS){
logger.error("Accepting user: "+mainAuthor.getEmailAddress()+ " Error: More than "+MAX_PARTNERS+" partner(s) added to project idea.");
return new Pair<Boolean, String>(false, "You may not add more than "+MAX_PARTNERS+" partner to the project idea"); //You may not add more than a specified number of partners.
}
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if(reloadedIdea.getProjectClass().getCode().equals(ProjectClass.BACHELOR) && students.isEmpty()){
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: No partner selected on bachelor level thesis.");
return new Pair<Boolean, String>(false, "You need to select a partner when the idea is on bachelor level"); //You need to select a partner if the idea is on bachelor level.
}
Student author = studentService.findByUser(mainAuthor);
if(students.contains(author)) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: Accepting user selected as his/her own partner.");
return new Pair<Boolean, String>(false, "You may not select yourself as partner"); //You may not select yourself as partner.
}
if(authorParticipatingOnIdea(author)) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: Author already attached to a taken project idea.");
return new Pair<Boolean, String>(false, "You may only be part of one project idea."); //You may only be part of one taken idea at once.
}
for(Student s : students) {
if(authorParticipatingOnIdea(s)) {
logger.error("Accepting user: " + mainAuthor.getEmailAddress() + " Error: Co-author already attached to a taken project idea.");
return new Pair<Boolean, String>(false, "Your project partner is already part of another project idea");
}
}
return new Pair<Boolean, String>(true, "Validation successful");
}
@Override
public Pair<Boolean, String> validatePartnerAcceptance(User user) {
Student author = studentService.findByUser(user);
if(partnerAlreadyParticipatingOnIdea(author)){
logger.error("Accepting user: " + user.getEmailAddress() + " Error: May not accept to be a partner if already participating in another idea.");
return new Pair<Boolean, String>(false, "You may not accept to be a partner if already participating in another idea");
}
return new Pair<Boolean, String>(true,"Validation passed");
}
@Override
@Transactional (readOnly = false)
public void partnerAcceptIdea(SupervisorIdea idea, User loggedInUser) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
Student author = studentService.findByUser(loggedInUser);
for (IdeaParticipation ip : reloadedIdea.getIdeaParticipations()) {
if(ip.getStudent().equals(author))
ip.setConfirmed(true);
}
if(reloadedIdea.getApplicationPeriod()==null) {
reloadedIdea.setApplicationPeriod(applicationPeriodService.getCurrentPeriod(new Date(), reloadedIdea.getProjectClass()));
}
}
@Override
@Transactional ( readOnly = false )
public void declineIdea(SupervisorIdea idea) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
//Remove participations
for (IdeaParticipation ip : reloadedIdea.getIdeaParticipations()) {
Student s = ip.getStudent();
s.removeIdeaParticipation(ip);
}
//Remove first meeting info if existing
if(reloadedIdea.getFirstMeeting()!=null)
firstMeetingService.delete(reloadedIdea.getFirstMeeting().getId());
reloadedIdea.setFirstMeeting(null);
//Erase watson boxes
reloadedIdea.setWatson(new Watson());
//Remove application period association
reloadedIdea.setApplicationPeriod(null);
//Change status back to waiting
reloadedIdea.setIdeaStatus(IdeaStatus.WAITING);
}
@Override
@Transactional ( readOnly = false )
public void updateIdea(SupervisorIdea idea) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if(idea.getWatson().getWhat()!=null)
reloadedIdea.getWatson().setWhat(idea.getWatson().getWhat());
if(idea.getWatson().getWhy()!=null)
reloadedIdea.getWatson().setWhy(idea.getWatson().getWhy());
if(idea.getWatson().getTheoryHow()!=null)
reloadedIdea.getWatson().setTheoryHow(idea.getWatson().getTheoryHow());
if(idea.getWatson().getPracticalHow()!=null)
reloadedIdea.getWatson().setPracticalHow(idea.getWatson().getPracticalHow());
}
@Override
public void checkForExpiredParticipation(SupervisorIdea idea, int confirmationDays) {
Date expirationDate = new DateTime().minusDays(confirmationDays).toDate();
for(IdeaParticipation ip : idea.getIdeaParticipations()) {
if(!ip.isConfirmed()&&ip.getDateCreated().compareTo(expirationDate)<0) {
logger.info(ip.getStudent() + " did not confirm participation on idea: "+idea.getTitle() + ". Removing participants from the idea");
declineIdea(idea);
}
}
}
@Override
@Transactional ( readOnly = false)
public SupervisorIdea saveMeeting(SupervisorIdea idea, Date date, String desc) {
SupervisorIdea reloadedIdea = supervisorIdeaRepo.findOne(idea.getId());
if (reloadedIdea.getFirstMeeting()!=null) {
reloadedIdea.getFirstMeeting().setFirstMeetingDate(date);
reloadedIdea.getFirstMeeting().setDescription(desc);
} else {
FirstMeeting meeting = new FirstMeeting(date, desc, reloadedIdea);
meeting = firstMeetingService.save(meeting);
reloadedIdea.setFirstMeeting(meeting);
}
return reloadedIdea;
}
@Override
@Transactional
public boolean hasTakenIdeas(User authorUser, boolean confirmed) {
Student author = studentService.findByUser(authorUser);
// find unconfirmed ideas by author
List<SupervisorIdea> ideas = findIdeas(IdeaStatus.TAKEN, author, confirmed);
if(!ideas.isEmpty())
return true;
else
return false;
}
@Override
public boolean hasUnconfirmedAuthor(SupervisorIdea idea){
Set<IdeaParticipation> ipList = idea.getIdeaParticipations();
for (IdeaParticipation ip : ipList) {
if(!ip.isConfirmed()) {
return true;
}
}
return false;
}
@Override
public boolean hasUnfinishedWatson(SupervisorIdea idea){
Watson watson = idea.getWatson();
return watson.getWhat().equals("")||watson.getWhy().equals("")||watson.getPracticalHow().equals("")||watson.getTheoryHow().equals("");
}
// Only editable if idea status is waiting and the current user is the creator
@Override
public boolean isIdeaEditable(SupervisorIdea idea, User currentUser) {
return idea.getIdeaStatus().equals(IdeaStatus.WAITING)&&idea.getCreator().getUser().equals(currentUser);
}
@Override
public boolean isAdminDeletable(SupervisorIdea idea) {
return idea.getIdeaStatus().equals(IdeaStatus.WAITING);
}
@Override
public Page<SupervisorIdea> findAll(FilterParams params, Pageable pageable) {
if(params!=null)
return supervisorIdeaRepo.findAll(fromParams(params), pageable);
else
return supervisorIdeaRepo.findAll(pageable);
}
@Override
public Page<SupervisorIdea> findByStatus(IdeaStatus status, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status), pageable);
}
@Override
public Page<SupervisorIdea> findByStatusAndParams(IdeaStatus status, FilterParams params, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status).and(predicateFromParams(params)), pageable);
}
@Override
public Page<SupervisorIdea> findByStatusAndCapabilities(IdeaStatus status, FilterParams params, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status).and(capabilityFilter(params.getLevels())), pageable);
}
@Override
public Page<SupervisorIdea> findIdeasWithoutProjects(Employee supervisor, Pageable pageable) {
return supervisorIdeaRepo.findAll(bySupervisor(supervisor).and(projectCreated(false)).and(byStatus(IdeaStatus.TAKEN).or(byStatus(IdeaStatus.COMPLETED))), pageable);
}
@Override
public List<SupervisorIdea> findByStatus(IdeaStatus status) {
Iterable<SupervisorIdea> iterable = supervisorIdeaRepo.findAll(byStatus(status));
return constructList(iterable);
}
@Override
public List<SupervisorIdea> findByStatusAndAuthor(IdeaStatus status, Student author) {
List<SupervisorIdea> ideas = supervisorIdeaRepo.findIdeasByAuthorAndStatus(author, status);
return ideas;
}
@Override
public List<SupervisorIdea> findIdeas(IdeaStatus status, Student author, boolean confirmed) {
List<SupervisorIdea> ideas = supervisorIdeaRepo.findIdeas(author, status, confirmed);
return ideas;
}
@Override
public List<SupervisorIdea> findIdeas(Student author) {
List<SupervisorIdea> ideas = supervisorIdeaRepo.findIdeas(author);
@ -402,194 +420,200 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
return ideas;
}
@Override
public List<SupervisorIdea> findIdeasWithoutProjects() {
Iterable<SupervisorIdea> iterable = supervisorIdeaRepo.findAll(projectCreated(false).and(byStatus(IdeaStatus.TAKEN).or(byStatus(IdeaStatus.COMPLETED))));
return constructList(iterable);
}
@Override
public List<SupervisorIdea> findIdeasWithoutProjects() {
Iterable<SupervisorIdea> iterable = supervisorIdeaRepo.findAll(projectCreated(false).and(byStatus(IdeaStatus.TAKEN).or(byStatus(IdeaStatus.COMPLETED))));
return constructList(iterable);
public Long countByStatus(IdeaStatus status) {
return supervisorIdeaRepo.count(byStatus(status));
}
@Override
public Long countIdeas(IdeaStatus status, Employee supervisor, ProjectClass pc) {
return supervisorIdeaRepo.count(byStatus(status)
.and(bySupervisor(supervisor))
.and(byLevel(pc))
.and(acceptedAfter(supervisor.getCountFromDate(pc))));
}
@Override
public Long countByAuthorAndStatus(Student author, IdeaStatus status) {
return supervisorIdeaRepo.countIdeasByAuthorAndStatus(author, status);
}
@Override
public Long count(FilterParams params) {
return supervisorIdeaRepo.count(fromParams(params));
//return supervisorIdeaRepo.count(predicateFromParams(params));
}
@Override
public Long countByStatusAndParams(IdeaStatus status, FilterParams params) {
return supervisorIdeaRepo.count(byStatus(status).and(predicateFromParams(params)));
}
@Override
public Long countIdeasWithoutProjects(Employee supervisor) {
return supervisorIdeaRepo.count(bySupervisor(supervisor).and(projectCreated(false)).and(byStatus(IdeaStatus.TAKEN).or(byStatus(IdeaStatus.COMPLETED))));
}
@Override
public boolean authorParticipatingOnIdea(User user) {
Student author = studentService.findByUser(user);
return authorParticipatingOnIdea(author);
}
@Override
public String getIdeaStatus(SupervisorIdea idea) {
if(idea.getIdeaStatus().equals(IdeaStatus.WAITING))
return "Waiting for students to select";
if(idea.getIdeaStatus().equals(IdeaStatus.TAKEN)) {
if(hasUnconfirmedAuthor(idea))
return "Waiting for partner to accept";
else if(hasUnfinishedWatson(idea))
return "Waiting for Watson box details";
else if(applicationPeriodService.courseStartIsReached(idea.getApplicationPeriod()))
return "Matched, course started, awaiting project creation";
else
return "Matched, course starting "+new DateFormatter().createFormattedString(idea.getApplicationPeriod().getCourseStartDate());
}
if(idea.getIdeaStatus().equals(IdeaStatus.INACTIVE))
return "Inactivated";
if(idea.getIdeaStatus().equals(IdeaStatus.COMPLETED)&&idea.getProject()!=null)
return "Matched, project created";
else
return "";
}
private Predicate predicateFromParams(FilterParams params) {
return levelFilter(params.getLevels()).and(bySupervisor(params.getSupervisor()));
}
private BooleanBuilder fromParams(FilterParams params) {
BooleanBuilder bb = new BooleanBuilder();
if(params.getLevels()!=null)
bb.and(levelFilter(params.getLevels()));
if(params.getSupervisor()!=null)
bb.and(bySupervisor(params.getSupervisor()));
if(params.getCreatedAfter()!=null)
bb.and(startedBetween(params.getCreatedAfter(), params.getCreatedBefore()));
if(params.getTitleContains()!=null&&params.getTitleContains().length()>=3)
bb.and(ideaTitleContains(params.getTitleContains()));
System.out.println(bb.getArgs());
return bb;
}
private Predicate inSupervisorList(List<Employee> list) {
return QSupervisorIdea.supervisorIdea.creator.in(list);
}
private BooleanBuilder capabilityFilter(Collection<ProjectClass> levels){
BooleanBuilder e = new BooleanBuilder();
if (levels != null && !levels.isEmpty()) {
for (ProjectClass level : levels) {
List<Employee> list = supervisorService
.getSupervisorsWithinLimits(level);
if (list.isEmpty()) { // If no capable supervisors exist, make
// sure no ideas is returned.
return e.and(QSupervisorIdea.supervisorIdea.projectClass.isNull());
} else
e.or(byLevel(level).and(inSupervisorList(list)).and(isHidden(false)));
}
return e;
} else {
return e.and(QSupervisorIdea.supervisorIdea.projectClass.isNull());
}
}
@Override
public Long countByStatus(IdeaStatus status) {
return supervisorIdeaRepo.count(byStatus(status));
private BooleanBuilder levelFilter(Collection<ProjectClass> levels){
BooleanBuilder e = new BooleanBuilder();
if(levels!=null && !levels.isEmpty()){
for (ProjectClass level : levels) {
e.or(byLevel(level));
}
return e;
}
else {
e.and(QSupervisorIdea.supervisorIdea.projectClass.isNull());
return e;
}
}
@Override
public Long countIdeas(IdeaStatus status, Employee supervisor, ProjectClass pc) {
return supervisorIdeaRepo.count(byStatus(status)
.and(bySupervisor(supervisor))
.and(byLevel(pc))
.and(acceptedAfter(supervisor.getCountFromDate(pc))));
private BooleanExpression bySupervisor(Employee supervisor) {
if(supervisor!=null){
return QSupervisorIdea.supervisorIdea.creator.eq(supervisor);
} else {
return null;
}
}
@Override
public Long countByAuthorAndStatus(Student author, IdeaStatus status) {
return supervisorIdeaRepo.countIdeasByAuthorAndStatus(author, status);
}
@Override
public Long count(FilterParams params) {
return supervisorIdeaRepo.count(fromParams(params));
//return supervisorIdeaRepo.count(predicateFromParams(params));
}
@Override
public Long countByStatusAndParams(IdeaStatus status, FilterParams params) {
return supervisorIdeaRepo.count(byStatus(status).and(predicateFromParams(params)));
}
@Override
public Long countIdeasWithoutProjects(Employee supervisor) {
return supervisorIdeaRepo.count(bySupervisor(supervisor).and(projectCreated(false)).and(byStatus(IdeaStatus.TAKEN).or(byStatus(IdeaStatus.COMPLETED))));
}
@Override
public boolean authorParticipatingOnIdea(User user) {
Student author = studentService.findByUser(user);
return authorParticipatingOnIdea(author);
}
@Override
public String getIdeaStatus(SupervisorIdea idea) {
if (idea.getIdeaStatus().equals(IdeaStatus.WAITING))
return "Waiting for students to select";
if (idea.getIdeaStatus().equals(IdeaStatus.TAKEN)) {
if (hasUnconfirmedAuthor(idea))
return "Waiting for partner to accept";
else if (hasUnfinishedWatson(idea))
return "Waiting for Watson box details";
else if (applicationPeriodService.courseStartIsReached(idea.getApplicationPeriod()))
return "Matched, course started, awaiting project creation";
else
return "Matched, course starting " + new DateFormatter().createFormattedString(idea.getApplicationPeriod().getCourseStartDate());
}
if (idea.getIdeaStatus().equals(IdeaStatus.COMPLETED) && idea.getProject() != null)
return "Matched, project created";
else
return "";
}
private Predicate predicateFromParams(FilterParams params) {
return levelFilter(params.getLevels()).and(bySupervisor(params.getSupervisor()));
}
private BooleanBuilder fromParams(FilterParams params) {
BooleanBuilder bb = new BooleanBuilder();
if (params.getLevels() != null)
bb.and(levelFilter(params.getLevels()));
if (params.getSupervisor() != null)
bb.and(bySupervisor(params.getSupervisor()));
if (params.getCreatedAfter() != null)
bb.and(startedBetween(params.getCreatedAfter(), params.getCreatedBefore()));
if (params.getTitleContains() != null && params.getTitleContains().length() >= 3)
bb.and(ideaTitleContains(params.getTitleContains()));
System.out.println(bb.getArgs());
return bb;
}
private Predicate inSupervisorList(List<Employee> list) {
return QSupervisorIdea.supervisorIdea.creator.in(list);
}
private BooleanBuilder capabilityFilter(Collection<ProjectClass> levels) {
BooleanBuilder e = new BooleanBuilder();
if (levels != null && !levels.isEmpty()) {
for (ProjectClass level : levels) {
List<Employee> list = supervisorService
.getSupervisorsWithinLimits(level);
if (list.isEmpty()) { // If no capable supervisors exist, make
// sure no ideas is returned.
return e.and(QSupervisorIdea.supervisorIdea.projectClass.isNull());
} else
e.or(byLevel(level).and(inSupervisorList(list)).and(isHidden(false)));
}
return e;
} else {
return e.and(QSupervisorIdea.supervisorIdea.projectClass.isNull());
}
}
private BooleanBuilder levelFilter(Collection<ProjectClass> levels) {
BooleanBuilder e = new BooleanBuilder();
if (levels != null && !levels.isEmpty()) {
for (ProjectClass level : levels) {
e.or(byLevel(level));
}
return e;
} else {
e.and(QSupervisorIdea.supervisorIdea.projectClass.isNull());
return e;
}
}
private BooleanExpression bySupervisor(Employee supervisor) {
if (supervisor != null) {
return QSupervisorIdea.supervisorIdea.creator.eq(supervisor);
} else {
return null;
}
}
private BooleanExpression projectCreated(boolean isCreated) {
if (isCreated)
return QSupervisorIdea.supervisorIdea.project.isNotNull();
else
return QSupervisorIdea.supervisorIdea.project.isNull();
}
private BooleanExpression acceptedAfter(Date acceptedAfter) {
if (acceptedAfter != null)
return QSupervisorIdea.supervisorIdea.ideaParticipations.any().dateCreated.after(acceptedAfter);
else
return null;
}
private BooleanExpression ideaTitleContains(String titleContains) {
if (titleContains != null)
return QSupervisorIdea.supervisorIdea.title.contains(titleContains);
else
return null;
}
private BooleanExpression startedBetween(Date from, Date to) {
if (from != null && to != null) {
return QSupervisorIdea.supervisorIdea.dateCreated.between(from, to);
} else
return null;
}
private BooleanExpression byLevel(ProjectClass pc) {
return QSupervisorIdea.supervisorIdea.projectClass.eq(pc);
}
private BooleanExpression byStatus(IdeaStatus status) {
return QSupervisorIdea.supervisorIdea.ideaStatus.eq(status);
}
private BooleanExpression isHidden(boolean isHidden) {
return QSupervisorIdea.supervisorIdea.hidden.eq(isHidden);
}
public boolean authorParticipatingOnIdea(Student author) {
Long supervisorIdeas = countByAuthorAndStatus(author, IdeaStatus.TAKEN);
Long studentIdeas = studentIdeaService.countActiveByAuthor(author);
if (supervisorIdeas + studentIdeas == 0)
return false;
else
return true;
}
private boolean partnerAlreadyParticipatingOnIdea(Student author) {
Long ideas = countByAuthorAndStatus(author, IdeaStatus.TAKEN);
Long studentIdeas = studentIdeaService.countActiveByAuthor(author);
if (ideas + studentIdeas == 1)
return false;
else
return true;
}
private List<SupervisorIdea> constructList(Iterable<SupervisorIdea> ideas) {
private BooleanExpression projectCreated(boolean isCreated) {
if(isCreated)
return QSupervisorIdea.supervisorIdea.project.isNotNull();
else
return QSupervisorIdea.supervisorIdea.project.isNull();
}
private BooleanExpression acceptedAfter(Date acceptedAfter) {
if(acceptedAfter!=null)
return QSupervisorIdea.supervisorIdea.ideaParticipations.any().dateCreated.after(acceptedAfter);
else
return null;
}
private BooleanExpression ideaTitleContains(String titleContains) {
if(titleContains!=null)
return QSupervisorIdea.supervisorIdea.title.contains(titleContains);
else
return null;
}
private BooleanExpression startedBetween(Date from, Date to) {
if(from!=null&&to!=null) {
return QSupervisorIdea.supervisorIdea.dateCreated.between(from, to);
}
else
return null;
}
private BooleanExpression byLevel(ProjectClass pc){
return QSupervisorIdea.supervisorIdea.projectClass.eq(pc);
}
private BooleanExpression byStatus(IdeaStatus status){
return QSupervisorIdea.supervisorIdea.ideaStatus.eq(status);
}
private BooleanExpression isHidden(boolean isHidden){
return QSupervisorIdea.supervisorIdea.hidden.eq(isHidden);
}
public boolean authorParticipatingOnIdea(Student author) {
Long supervisorIdeas = countByAuthorAndStatus(author, IdeaStatus.TAKEN);
Long studentIdeas = studentIdeaService.countActiveByAuthor(author);
if(supervisorIdeas+studentIdeas==0)
return false;
else
return true;
}
private boolean partnerAlreadyParticipatingOnIdea(Student author) {
Long ideas = countByAuthorAndStatus(author, IdeaStatus.TAKEN);
Long studentIdeas = studentIdeaService.countActiveByAuthor(author);
if(ideas+studentIdeas==1)
return false;
else
return true;
}
private List<SupervisorIdea> constructList(Iterable<SupervisorIdea> ideas) {
List<SupervisorIdea> list = new ArrayList<SupervisorIdea>();
for (SupervisorIdea idea : ideas) {
list.add(idea);

@ -19,6 +19,7 @@ public interface SupervisorIdeaService extends GenericService<SupervisorIdea, Lo
Page<SupervisorIdea> findByStatusAndParams(IdeaStatus status, FilterParams params, Pageable pageable);
Page<SupervisorIdea> findByStatusAndCapabilities(IdeaStatus status, FilterParams params, Pageable pageable);
Page<SupervisorIdea> findIdeasWithoutProjects(Employee supervisor, Pageable pageable);
List<SupervisorIdea> findByStatus(IdeaStatus status);
List<SupervisorIdea> findByStatusAndAuthor(IdeaStatus status, Student author);
List<SupervisorIdea> findIdeas(IdeaStatus status, Student author, boolean confirmed);
List<SupervisorIdea> findIdeas(Student author);
@ -41,7 +42,8 @@ public interface SupervisorIdeaService extends GenericService<SupervisorIdea, Lo
void checkForExpiredParticipation(SupervisorIdea idea, int confirmationDays);
void changeSupervisor(SupervisorIdea idea, Employee newSupervisor);
void removeAuthor(SupervisorIdea idea, Student author);
void inactivateIdea(SupervisorIdea idea);
SupervisorIdea saveMeeting(SupervisorIdea idea, Date date, String desc);
boolean hasTakenIdeas(User authorUser, boolean confirmed);
@ -108,6 +110,5 @@ public interface SupervisorIdeaService extends GenericService<SupervisorIdea, Lo
}
}
}

@ -138,7 +138,7 @@ public class SupervisorProjectIdeaOverviewPanel extends Panel {
Item<ICellPopulator<SupervisorIdea>> item,
String componentId, IModel<SupervisorIdea> ideaModel) {
SupervisorIdea idea = ideaModel.getObject();
if(idea.getIdeaStatus().equals(IdeaStatus.WAITING))
if(idea.getIdeaStatus().equals(IdeaStatus.WAITING)||idea.getIdeaStatus().equals(IdeaStatus.INACTIVE))
item.add(new Label(componentId, "-"));
else if (idea.getFirstMeeting()!=null)
item.add(new Label(componentId, new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(idea.getFirstMeeting().getFirstMeetingDate())));

@ -42,6 +42,8 @@ public class Scheduler {
workerSchedules.add(new WorkerSchedule<AbstractWorker>(UserImportWorker.class,"Remote supervisor (and projects) bulk import",daily(0, 05), dayPeriod(), ctx));
workerSchedules.add(new WorkerSchedule<AbstractWorker>(ExpiredIdeaParticipationsWorker.class, "Unconfirmed project ideas worker", daily(23,30), dayPeriod(), ctx));
workerSchedules.add(new WorkerSchedule<AbstractWorker>(WatsonCompletionWorker.class, "Check for incomplete Watson boxes", daily(23,45), dayPeriod(), ctx));
}
private Scheduler(){

@ -0,0 +1,52 @@
package se.su.dsv.scipro.workerthreads;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.springdata.services.ApplicationPeriodService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
@Component
public class WatsonCompletionWorker extends AbstractWorker {
@Autowired
private SupervisorIdeaService supervisorIdeaService;
@Autowired
private ApplicationPeriodService applicationPeriodService;
private Logger logger = Logger.getLogger(WatsonCompletionWorker.class);
@Override
protected void doWork() {
this.beginTransaction();
try{
logger.info("Searching for ideas to inactivate..");
List<SupervisorIdea> matchedIdeas = supervisorIdeaService.findByStatus(IdeaStatus.TAKEN);
if(!matchedIdeas.isEmpty()){
logger.info("Found "+ matchedIdeas.size()+ " matched ideas. Checking if application period end date is reached");
for (SupervisorIdea idea : matchedIdeas) {
if(applicationPeriodService.endDateIsReached(idea.getApplicationPeriod())){
if(supervisorIdeaService.hasUnfinishedWatson(idea)){
supervisorIdeaService.inactivateIdea(idea);
logger.info("Found unfinished Watson boxes, inactivating idea: " + idea.getTitle());
}
}
}
} else {
logger.info("No matched ideas available to check for incomplete Watson boxes");
}
commitTransaction();
} catch (Exception e){
this.rollbackTransaction();
this.setSuccessfulWorker(false);
throw new RuntimeException(e);
}
}
}