added first meeting entity and fields for adding this in the supervisor project idea details dialog.

This commit is contained in:
Emil Siverhall 2012-08-02 13:19:44 +02:00
parent 966616f297
commit 9484791d60
10 changed files with 258 additions and 8 deletions

@ -0,0 +1,76 @@
package se.su.dsv.scipro.match.dataobject;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.apache.wicket.IClusterable;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Table(name = "first_meeting")
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class FirstMeeting implements IClusterable {
private static final long serialVersionUID = 1659431236791209714L;
@Id
@GeneratedValue
private Long id;
@Basic(optional=false)
private Date firstMeetingDate;
@Column(nullable = false, length = 1024)
private String description;
@OneToOne(optional=false)
private SupervisorIdea supervisorIdea;
public FirstMeeting(){
}
public FirstMeeting(Date firstMeetingDate, String description, SupervisorIdea supervisorIdea) {
this.firstMeetingDate = firstMeetingDate;
this.description = description;
this.supervisorIdea = supervisorIdea;
}
public Date getFirstMeetingDate() {
return firstMeetingDate;
}
public void setFirstMeetingDate(Date firstMeetingDate) {
this.firstMeetingDate = firstMeetingDate;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Long getId() {
return id;
}
public void setSupervisorIdea(SupervisorIdea supervisorIdea) {
this.supervisorIdea = supervisorIdea;
}
public SupervisorIdea getSupervisorIdea() {
return supervisorIdea;
}
}

@ -2,11 +2,11 @@ package se.su.dsv.scipro.match.dataobject;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
@ -34,6 +34,9 @@ public class SupervisorIdea extends Idea {
@Column(nullable = false, length = 1024)
private String requirements;
@OneToOne(mappedBy="supervisorIdea", orphanRemoval = true, optional = true)
private FirstMeeting firstMeeting;
@Override
public Long getId() {
return id;
@ -109,4 +112,12 @@ public class SupervisorIdea extends Idea {
return false;
return true;
}
public void setFirstMeeting(FirstMeeting firstMeeting) {
this.firstMeeting = firstMeeting;
}
public FirstMeeting getFirstMeeting() {
return firstMeeting;
}
}

@ -0,0 +1,12 @@
package se.su.dsv.scipro.springdata.repos;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
@Transactional(readOnly = true)
public interface FirstMeetingRepo extends JpaRepository<FirstMeeting, Long>, QueryDslPredicateExecutor<FirstMeeting> {
}

@ -20,11 +20,13 @@ import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.FirstMeeting;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
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.springdata.repos.FirstMeetingRepo;
import se.su.dsv.scipro.springdata.repos.SupervisorIdeaRepo;
import se.su.dsv.scipro.springdata.services.ApplicationPeriodService;
import se.su.dsv.scipro.springdata.services.StudentService;
@ -47,6 +49,9 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
private SupervisorService supervisorService;
@Resource
private ApplicationPeriodService applicationPeriodService;
@Resource
private FirstMeetingRepo firstMeetingRepo;
private transient Logger logger = Logger.getLogger(SupervisorIdeaService.class);
private int MAX_PARTNERS = 1;
@ -212,6 +217,21 @@ public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorId
reloadedIdea.getWatson().setPracticalHow(idea.getWatson().getPracticalHow());
}
@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 = firstMeetingRepo.save(meeting);
reloadedIdea.setFirstMeeting(meeting);
}
return reloadedIdea;
}
@Override
@Transactional
public boolean hasTakenIdeas(User authorUser, boolean confirmed) {

@ -2,6 +2,7 @@ package se.su.dsv.scipro.springdata.services;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
@ -35,6 +36,7 @@ public interface SupervisorIdeaService extends GenericService<SupervisorIdea, Lo
void partnerAcceptIdea(SupervisorIdea idea, User loggedInUser);
void declineIdea(SupervisorIdea idea);
void updateIdea(SupervisorIdea idea);
SupervisorIdea saveMeeting(SupervisorIdea idea, Date date, String desc);
boolean hasTakenIdeas(User authorUser, boolean confirmed);
boolean isIdeaEditable(SupervisorIdea idea, User currentUser);

@ -7,7 +7,27 @@
<body>
<wicket:panel>
<form wicket:id="form">
<div wicket:id="ideaDetails"></div>
<div class="append-bottom" wicket:id="ideaDetails"></div>
<div class="prepend-top" wicket:id="meetingEnclosure">
<div class="span-8 append-bottom info-box rounded-box last">
<p>
The students won't see who is the supervisor until the
application period course start date.
</p>
A time and date for the first meeting must be selected and
saved at least X days before application period course start date.
</div>
<div class="span-6">
<div class="span-8" wicket:id="feedback"></div>
<b>First meeting:</b><br />
<input wicket:id="dateField"/><br />
<b>Place:</b><br />
<textarea wicket:id="descriptionField"></textarea>
<input type="button" wicket:id="saveButton" value="Save meeting details"/>
</div>
</div>
</form>
</wicket:panel>
</body>

@ -1,19 +1,36 @@
package se.su.dsv.scipro.supervisor.panels;
import java.util.Date;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.extensions.markup.html.form.DateTextField;
import org.apache.wicket.extensions.yui.calendar.DatePicker;
import org.apache.wicket.markup.html.basic.EnclosureContainer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.project.panels.ProjectIdeaDetailsPanel;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
public class SupervisorIdeaDetailsPanel extends Panel {
public abstract class SupervisorIdeaDetailsPanel extends Panel {
@SpringBean
private SupervisorIdeaService ideaService;
public SupervisorIdeaDetailsPanel(String id, IModel<SupervisorIdea> model) {
super(id, model);
add(new SupervisorIdeaDetailsForm("form", model));
}
public abstract void updateTarget(AjaxRequestTarget target, SupervisorIdea idea);
private static final long serialVersionUID = 29731924490786784L;
private class SupervisorIdeaDetailsForm extends Form<SupervisorIdea> {
@ -23,6 +40,56 @@ public class SupervisorIdeaDetailsPanel extends Panel {
public SupervisorIdeaDetailsForm(String id, final IModel<SupervisorIdea> model) {
super(id, model);
add(new ProjectIdeaDetailsPanel("ideaDetails", model, true, true));
addFirstMeetingEnclosure(model, true);
}
private void addFirstMeetingEnclosure(final IModel<SupervisorIdea> model, boolean visibility) {
final FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setOutputMarkupId(true);
Date firstMeetingDate;
Model<String> descModel;
if (model.getObject().getFirstMeeting()!=null){
firstMeetingDate = model.getObject().getFirstMeeting().getFirstMeetingDate();
descModel = Model.of(model.getObject().getFirstMeeting().getDescription());
}
else {
firstMeetingDate = new Date();
descModel = new Model<String>();
}
final DateTextField dateField = new DateTextField("dateField", new Model<Date>(firstMeetingDate), "yyyy-MM-dd");
DatePicker datePicker = new DatePicker();
datePicker.setShowOnFieldClick(true);
dateField.add(datePicker);
final TextArea<String> meetingDescriptionField = new TextArea<String>("descriptionField", descModel);
AjaxSubmitLink saveLink = new AjaxSubmitLink("saveButton") {
private static final long serialVersionUID = -4841491128764249358L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
if(meetingDescriptionField.getModelObject()==null){
error("You need to specify a place for the meeting");
} else {
SupervisorIdea idea = ideaService.saveMeeting(model.getObject(), dateField.getModelObject(), meetingDescriptionField.getModelObject());
updateTarget(target, idea);
}
target.addComponent(feedback);
}
};
//Date field controls visibility of entire container.
dateField.setVisible(visibility);
EnclosureContainer firstMeetingEnclosure = new EnclosureContainer("meetingEnclosure", dateField);
firstMeetingEnclosure.add(feedback);
firstMeetingEnclosure.add(dateField);
firstMeetingEnclosure.add(meetingDescriptionField);
firstMeetingEnclosure.add(saveLink);
add(firstMeetingEnclosure);
}

@ -8,6 +8,7 @@
<div wicket:id="dialog">
<div wicket:id="dialogPanel"></div>
</div>
<div wicket:id="feedback"></div>
<form wicket:id="form">
<div class="span-5" wicket:id="levelFilter"></div>
<div class="span-5">

@ -9,6 +9,7 @@ import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
@ -43,8 +44,11 @@ public class SupervisorProjectIdeaOverviewPanel extends Panel {
public SupervisorProjectIdeaOverviewPanel(String id, final User supervisor) {
super(id);
FeedbackPanel feedback = new FeedbackPanel("feedback");
feedback.setOutputMarkupId(true);
add(feedback);
addDialog();
addDataTable(supervisor);
addDataTable(supervisor, feedback);
add(new FilterForm("form", supervisor));
}
@ -52,13 +56,13 @@ public class SupervisorProjectIdeaOverviewPanel extends Panel {
dialog = new Dialog("dialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(500);
dialog.setWidth(450);
dialog.setHeight(600);
dialog.add(new EmptyPanel("dialogPanel"));
add(dialog);
}
private void addDataTable(final User supervisor) {
private void addDataTable(final User supervisor, final FeedbackPanel feedback) {
add(genericDataPanel = new GenericDataPanel<SupervisorIdea>("dataPanel") {
private static final long serialVersionUID = -4539188306454725307L;
@ -87,9 +91,20 @@ public class SupervisorProjectIdeaOverviewPanel extends Panel {
private static final long serialVersionUID = 4667741924987868274L;
@Override
protected void onClick(IModel<SupervisorIdea> ideaModel,
protected void onClick(final IModel<SupervisorIdea> ideaModel,
AjaxRequestTarget target) {
dialog.replace(new SupervisorIdeaDetailsPanel("dialogPanel", ideaModel));
dialog.replace(new SupervisorIdeaDetailsPanel("dialogPanel", ideaModel){
private static final long serialVersionUID = -1970068053928444580L;
@Override
public void updateTarget(AjaxRequestTarget target, SupervisorIdea idea) {
dialog.close(target);
info("Meeting details saved");
ideaModel.setObject(idea);
target.addComponent(feedback);
}
});
dialog.setTitle("Selected supervisor project idea");
target.addComponent(dialog);
dialog.open(target);

@ -1,10 +1,14 @@
package se.su.dsv.scipro.springdata;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@ -29,6 +33,7 @@ import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
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;
import se.su.dsv.scipro.match.dataobject.Keyword;
@ -70,6 +75,7 @@ public class TestSupervisorIdea {
private SupervisorIdea waitingBachelorIdea, waitingMasterIdea, takenBachelorIdea, completedMasterIdea, waitingBachelor2, waitingMaster2, waitingBachelor3;
private ApplicationPeriod bachelorPeriod, masterPeriod;
private Keyword keyword1, keyword2;
private SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
@Before
public void startTransaction() throws Exception {
@ -410,6 +416,18 @@ public class TestSupervisorIdea {
Assert.assertNotNull(idea.getApplicationPeriod());
}
@Test
@Transactional
@Rollback
public void testCreateFirstMeeting() {
Date firstMeetingDate = date("2012-08-01");
FirstMeeting firstMeeting = new FirstMeeting(firstMeetingDate, "First meeting description", takenBachelorIdea);
takenBachelorIdea.setFirstMeeting(firstMeeting);
Assert.assertEquals(firstMeetingDate, takenBachelorIdea.getFirstMeeting().getFirstMeetingDate());
Assert.assertEquals("First meeting description", takenBachelorIdea.getFirstMeeting().getDescription());
Assert.assertEquals(takenBachelorIdea, takenBachelorIdea.getFirstMeeting().getSupervisorIdea());
}
// HELPER METHODS
private SupervisorIdea newIdea(ProjectClass pc, ApplicationPeriod ap, Employee supervisor, IdeaStatus ideaStatus) {
SupervisorIdea idea = new SupervisorIdea();
@ -455,4 +473,12 @@ public class TestSupervisorIdea {
}
return list;
}
private Date date(String dateString) {
try {
return date.parse(dateString);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}