Assign supervisor to student ideas no matter if target (goal) is reached ()

Fixes 

Reviewed-on: 
Reviewed-by: Andreas Svanberg <andreass@dsv.su.se>
Co-authored-by: Tom Zhao <tom.zhao@dsv.su.se>
Co-committed-by: Tom Zhao <tom.zhao@dsv.su.se>
This commit is contained in:
Tom Zhao 2025-02-18 09:59:23 +01:00 committed by Andreas Svanberg
parent b9f7dd5a49
commit 399d8f5275
4 changed files with 92 additions and 18 deletions
core/src/main/java/se/su/dsv/scipro
view/src/main
java/se/su/dsv/scipro/match
webapp/css
war/src/main/resources

@ -13,6 +13,7 @@ import java.util.*;
import java.util.function.Function;
import se.su.dsv.scipro.checklist.ChecklistCategory;
import se.su.dsv.scipro.file.FileUpload;
import se.su.dsv.scipro.match.*;
import se.su.dsv.scipro.match.ApplicationPeriod;
import se.su.dsv.scipro.match.Idea;
import se.su.dsv.scipro.match.IdeaService;
@ -85,16 +86,19 @@ public class DataInitializer implements Lifecycle {
private User stina_student;
private User sid_student;
private User simon_student;
private ProjectType bachelorClass;
private User sofia_student;
private Set<ResearchArea> researchAreas;
private Long researchAreaId = RESEARCH_AREA_ID;
private Set<Language> languages;
private ApplicationPeriod applicationPeriod;
private Keyword keyword1;
private Set<Language> languages = Set.of(Language.SWEDISH, Language.ENGLISH);
private Program program;
private ResearchArea researchArea1;
private ResearchArea researchArea2;
private Keyword keyword1;
private Keyword keyword2;
private ProjectType bachelorClass;
private ProjectType masterClass;
private ProjectType magisterClass;
private ApplicationPeriod applicationPeriod;
private Project project2;
@Transactional
@ -103,6 +107,7 @@ public class DataInitializer implements Lifecycle {
if (profile.getCurrentProfile() == Profiles.DEV && noUsers()) {
createDefaultProjectTypesIfNotDone();
createDefaultChecklistCategoriesIfNotDone();
createProgram();
createApplicationPeriodIfNotDone();
createGradingCriterionTemplateIfNotDone();
createResearchAreasForDemo();
@ -111,6 +116,8 @@ public class DataInitializer implements Lifecycle {
createUsers();
createMatchedIdea();
createProjects();
createTarget();
createStudentIdea();
createRoughDraftApproval();
}
if (profile.getCurrentProfile() == Profiles.DEV && noAdminUser()) {
@ -135,6 +142,15 @@ public class DataInitializer implements Lifecycle {
return userService.findByUsername(ADMIN + MAIL) == null;
}
private void createProgram() {
program = new Program();
program.setCode("AppCompSci");
program.setName("Tillämpad Datavetenskap");
program.setExternalId(123);
program.setNameEn("Applied Computer Science");
program = save(program);
}
private void createApplicationPeriodIfNotDone() {
applicationPeriod = new ApplicationPeriod("HT 2014");
applicationPeriod.setStartDate(LocalDate.now().minusDays(APPLICATION_PERIOD_START_MINUS_DAYS));
@ -150,12 +166,12 @@ public class DataInitializer implements Lifecycle {
keyword1 = new Keyword("IT");
keyword1.addResearchArea(researchArea1);
keyword1.addResearchArea(researchArea2);
save(keyword1);
keyword1 = save(keyword1);
Keyword keyword2 = new Keyword("Computers");
keyword2 = new Keyword("Computers");
keyword2.addResearchArea(researchArea1);
keyword2.addResearchArea(researchArea2);
save(keyword2);
keyword2 = save(keyword2);
}
private void createResearchAreasForDemo() {
@ -211,6 +227,11 @@ public class DataInitializer implements Lifecycle {
// can not be used as author on any idea
// can not be used as author on any project
createStudent("Stig");
// Used to test assign supervisor to student idea
// this student has a submitted idea, which has not assigned supervisor
// don't use this student for anything else
sofia_student = createStudent("Sofia");
}
private User createStudent(String firstName) {
@ -229,8 +250,11 @@ public class DataInitializer implements Lifecycle {
user.setUnit(u);
user.setResearchAreas(researchAreas);
user.setLanguages(languages);
user.setActiveAsSupervisor(true);
createBeta(user);
return user;
return save(user);
}
private User createUser(String firstName, String lastName) {
@ -304,6 +328,32 @@ public class DataInitializer implements Lifecycle {
save(getMagisterTemplate());
}
private void createTarget() {
Target target = new Target(eric_employee, applicationPeriod, bachelorClass);
target.setTarget(10);
save(target);
}
private void createStudentIdea() {
Idea idea = new Idea();
idea.setTitle("Fundamental Math Concepts of AI");
idea.setType(Idea.Type.STUDENT);
TholanderBox box = new TholanderBox();
box.setLiterature("Math AI Literature");
box.setBackground("Math AI Background");
box.setProblem("Math AI Problem");
box.setMethod("Math AI Method");
box.setInterests("Math AI Interests");
idea.setTholanderBox(box);
idea.setProjectType(bachelorClass);
idea.setApplicationPeriod(applicationPeriod);
List<Keyword> keywords = List.of(keyword1, keyword2);
ideaService.saveStudentIdea(idea, sofia_student, program, new HashSet<User>(), keywords, true);
}
private GradingReportTemplate getBachelorTemplate() {
GradingReportTemplate gradingReportTemplate = new GradingReportTemplate(
bachelorClass,

@ -205,17 +205,34 @@ public abstract class AbstractAdminIdeaPanel extends Panel {
ideaService.adminUnmatchIdea(idea, SciProSession.get().getUser());
info("Unmatched idea: " + idea.getTitle());
} else {
if (
targetService.hasTargetsLeft(
idea.getApplicationPeriod(),
newSelection,
idea.getProjectType()
)
) {
ideaService.changeSupervisor(idea, newSelection, SciProSession.get().getUser());
info("Supervisor changed");
ideaService.changeSupervisor(idea, newSelection, SciProSession.get().getUser());
Target currentTarget = targetService.findOne(
idea.getApplicationPeriod(),
newSelection,
idea.getProjectType()
);
Long countMatched = ideaService.countMatched(
idea.getApplicationPeriod(),
newSelection,
idea.getProjectType()
);
int targetCounter = (currentTarget == null) ? 0 : currentTarget.getTarget();
String msg =
"Supervisor changed: matched/target -> " +
countMatched +
" / " +
targetCounter +
" (" +
idea.getProjectType().getName() +
")";
if (countMatched > targetCounter) {
warn(msg);
} else {
error("The supervisor have reached current target numbers");
info(msg);
}
}
target.addListener(new AjaxFeedbackPanelUpdater());

@ -129,6 +129,12 @@ footer a:hover { color: #d95e00;}
border-color: #EBCCD1;
}
.feedbackPanelWARNING {
color: #000000;
background-color: #FFD105;
border-color: #EBCCD1;
}
.feedbackPanelINFO {
color: #3C763D;
background-color: #DFF0D8;

@ -9,6 +9,7 @@ spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.Ph
# We also need to set the implicit strategy to be JPA compliant, as we rely on this naming strategy for certain
# join tables (idea_Keyword vs idea_keyword)
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.show-sql=false
spring.mvc.servlet.path=/api