Allow changes to the reflection to be made after it's been submitted #13

Merged
ansv7779 merged 20 commits from 3412-supervisor-edit-reflection into develop 2024-11-21 19:20:48 +01:00
213 changed files with 2812 additions and 295 deletions
Showing only changes of commit 6a765a73d7 - Show all commits

View File

@ -0,0 +1,16 @@
name: Build and test
on:
- push
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: ./mvnw --batch-mode --update-snapshots verify

19
.mvn/wrapper/maven-wrapper.properties vendored Normal file
View File

@ -0,0 +1,19 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
wrapperVersion=3.3.2
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip

View File

@ -25,6 +25,8 @@ import se.su.dsv.scipro.report.GradingReportTemplateRepo;
import se.su.dsv.scipro.report.GradingReportTemplateRepoImpl; import se.su.dsv.scipro.report.GradingReportTemplateRepoImpl;
import se.su.dsv.scipro.report.OppositionReportRepo; import se.su.dsv.scipro.report.OppositionReportRepo;
import se.su.dsv.scipro.report.OppositionReportRepoImpl; import se.su.dsv.scipro.report.OppositionReportRepoImpl;
import se.su.dsv.scipro.report.SupervisorGradingReportRepository;
import se.su.dsv.scipro.report.SupervisorGradingReportRepositoryImpl;
import se.su.dsv.scipro.reviewing.DecisionRepository; import se.su.dsv.scipro.reviewing.DecisionRepository;
import se.su.dsv.scipro.reviewing.DecisionRepositoryImpl; import se.su.dsv.scipro.reviewing.DecisionRepositoryImpl;
import se.su.dsv.scipro.reviewing.ReviewerTargetRepository; import se.su.dsv.scipro.reviewing.ReviewerTargetRepository;
@ -59,5 +61,6 @@ public class RepositoryModule extends AbstractModule {
bind(FinalSeminarRepository.class).to(FinalSeminarRepositoryImpl.class); bind(FinalSeminarRepository.class).to(FinalSeminarRepositoryImpl.class);
bind(ReviewerTargetRepository.class).to(ReviewerTargetRepositoryImpl.class); bind(ReviewerTargetRepository.class).to(ReviewerTargetRepositoryImpl.class);
bind(DecisionRepository.class).to(DecisionRepositoryImpl.class); bind(DecisionRepository.class).to(DecisionRepositoryImpl.class);
bind(SupervisorGradingReportRepository.class).to(SupervisorGradingReportRepositoryImpl.class);
} }
} }

View File

@ -10,6 +10,7 @@ import se.su.dsv.scipro.milestones.service.MilestoneActivityTemplateService;
import se.su.dsv.scipro.profiles.CurrentProfile; import se.su.dsv.scipro.profiles.CurrentProfile;
import se.su.dsv.scipro.profiles.Profiles; import se.su.dsv.scipro.profiles.Profiles;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.report.AbstractGradingCriterion;
import se.su.dsv.scipro.report.GradingCriterionPointTemplate; import se.su.dsv.scipro.report.GradingCriterionPointTemplate;
import se.su.dsv.scipro.report.GradingReportTemplate; import se.su.dsv.scipro.report.GradingReportTemplate;
import se.su.dsv.scipro.security.auth.roles.Roles; import se.su.dsv.scipro.security.auth.roles.Roles;
@ -20,6 +21,7 @@ import jakarta.inject.Provider;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.Month;
import java.util.*; import java.util.*;
public class DataInitializer implements Lifecycle { public class DataInitializer implements Lifecycle {
@ -232,19 +234,20 @@ public class DataInitializer implements Lifecycle {
} }
private void createGradingCriterionTemplateIfNotDone() { private void createGradingCriterionTemplateIfNotDone() {
save(getBachelorTemplate(0)); save(getBachelorTemplate());
save(getBachelorTemplate(ProjectType.HP_15)); save(getBachelorTemplate());
save(getBachelorTemplate(ProjectType.HP_30)); save(getBachelorTemplate());
save(getMasterTemplate(0)); save(getMasterTemplate());
save(getMasterTemplate(ProjectType.HP_15)); save(getMasterTemplate());
save(getMasterTemplate(ProjectType.HP_30)); save(getMasterTemplate());
save(getMagisterTemplate(0)); save(getMagisterTemplate());
save(getMagisterTemplate(ProjectType.HP_15)); save(getMagisterTemplate());
save(getMagisterTemplate(ProjectType.HP_30)); save(getMagisterTemplate());
} }
private GradingReportTemplate getBachelorTemplate(int credits) { private GradingReportTemplate getBachelorTemplate() {
GradingReportTemplate gradingReportTemplate = new GradingReportTemplate(bachelorClass, credits); GradingReportTemplate gradingReportTemplate = new GradingReportTemplate(bachelorClass,
LocalDate.of(2024, Month.JANUARY, 1));
List<GradingCriterionPointTemplate> gradingCriterionPointTemplates = initPointTemplates(); List<GradingCriterionPointTemplate> gradingCriterionPointTemplates = initPointTemplates();
gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder() gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder()
@ -401,7 +404,7 @@ public class DataInitializer implements Lifecycle {
.description("För 2 poäng krävs dessutom: att oppositionsrapporten ingående och välbalanserat beskriver styrkor och svagheter hos det utvärderade arbetet ur flera aspekter samt att den innehåller tydliga och välmotiverade förslag till förbättringar.") .description("För 2 poäng krävs dessutom: att oppositionsrapporten ingående och välbalanserat beskriver styrkor och svagheter hos det utvärderade arbetet ur flera aspekter samt att den innehåller tydliga och välmotiverade förslag till förbättringar.")
.descriptionEn("For 2 points the following is also required: that the opposition report thoroughly and in a well-balanced way describes from numerous aspects the strengths and weaknesses of the evaluated thesis and that it offers clear and well-motivated suggestions for improvements.") .descriptionEn("For 2 points the following is also required: that the opposition report thoroughly and in a well-balanced way describes from numerous aspects the strengths and weaknesses of the evaluated thesis and that it offers clear and well-motivated suggestions for improvements.")
.build()); .build());
gradingReportTemplate.addIndividualCriterion("Ö1 Oppositionsrapport", "Ö1 Opposition report", 1, gradingCriterionPointTemplates); gradingReportTemplate.addIndividualCriterion("Ö1 Oppositionsrapport", "Ö1 Opposition report", 1, gradingCriterionPointTemplates, AbstractGradingCriterion.Flag.OPPOSITION);
gradingCriterionPointTemplates = initPointTemplates(); gradingCriterionPointTemplates = initPointTemplates();
gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder() gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder()
@ -441,13 +444,14 @@ public class DataInitializer implements Lifecycle {
.description("För 1 poäng krävs: att förmåga har uppvisats att reflektera över det genomförda examensarbetet genom individuellt författande av ett reflektionsdokument.") .description("För 1 poäng krävs: att förmåga har uppvisats att reflektera över det genomförda examensarbetet genom individuellt författande av ett reflektionsdokument.")
.descriptionEn("Requirement for 1 point: that the ability to reflect about the thesis work has been demonstrated through the individual writing of a reflection document.") .descriptionEn("Requirement for 1 point: that the ability to reflect about the thesis work has been demonstrated through the individual writing of a reflection document.")
.build()); .build());
gradingReportTemplate.addIndividualCriterion("Ö6 Reflektion", "Ö6 Reflection", 0, gradingCriterionPointTemplates).setFx(false); gradingReportTemplate.addIndividualCriterion("Ö6 Reflektion", "Ö6 Reflection", 0, gradingCriterionPointTemplates, AbstractGradingCriterion.Flag.REFLECTION).setFx(false);
return gradingReportTemplate; return gradingReportTemplate;
} }
private GradingReportTemplate getMasterTemplate(int credits) { private GradingReportTemplate getMasterTemplate() {
GradingReportTemplate gradingReportTemplateMaster = new GradingReportTemplate(masterClass, credits); GradingReportTemplate gradingReportTemplateMaster = new GradingReportTemplate(masterClass,
LocalDate.of(2024, Month.JANUARY, 1));
List<GradingCriterionPointTemplate> gradingCriterionPointTemplates = initPointTemplates(); List<GradingCriterionPointTemplate> gradingCriterionPointTemplates = initPointTemplates();
gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder() gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder()
@ -629,7 +633,8 @@ public class DataInitializer implements Lifecycle {
.description("För 2 poäng krävs dessutom: att oppositionsrapporten ingående och välbalanserat beskriver styrkor och svagheter hos det utvärderade arbetet ur flera aspekter samt att den innehåller tydliga och välmotiverade förslag till förbättringar.") .description("För 2 poäng krävs dessutom: att oppositionsrapporten ingående och välbalanserat beskriver styrkor och svagheter hos det utvärderade arbetet ur flera aspekter samt att den innehåller tydliga och välmotiverade förslag till förbättringar.")
.descriptionEn("For 2 points the following is also required: that the opposition report thoroughly and in a well-balanced way describes from numerous aspects the strengths and weaknesses of the evaluated thesis and that it offers clear and well-motivated suggestions for improvements.") .descriptionEn("For 2 points the following is also required: that the opposition report thoroughly and in a well-balanced way describes from numerous aspects the strengths and weaknesses of the evaluated thesis and that it offers clear and well-motivated suggestions for improvements.")
.build()); .build());
gradingReportTemplateMaster.addIndividualCriterion("Ö1 Oppositionsrapport", "Ö1 Opposition report", 1, gradingCriterionPointTemplates); gradingReportTemplateMaster.addIndividualCriterion("Ö1 Oppositionsrapport", "Ö1 Opposition report", 1, gradingCriterionPointTemplates,
AbstractGradingCriterion.Flag.OPPOSITION);
gradingCriterionPointTemplates = initPointTemplates(); gradingCriterionPointTemplates = initPointTemplates();
gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder() gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder()
@ -669,13 +674,14 @@ public class DataInitializer implements Lifecycle {
.description("För 1 poäng krävs: att förmåga har uppvisats att reflektera över det genomförda examensarbetet genom individuellt författande av ett reflektionsdokument.") .description("För 1 poäng krävs: att förmåga har uppvisats att reflektera över det genomförda examensarbetet genom individuellt författande av ett reflektionsdokument.")
.descriptionEn("Requirement for 1 point: that the ability to reflect about the thesis work has been demonstrated through the individual writing of a reflection document.") .descriptionEn("Requirement for 1 point: that the ability to reflect about the thesis work has been demonstrated through the individual writing of a reflection document.")
.build()); .build());
gradingReportTemplateMaster.addIndividualCriterion("Ö6 Reflektion", "Ö6 Reflection", 1, gradingCriterionPointTemplates).setFx(false); gradingReportTemplateMaster.addIndividualCriterion("Ö6 Reflektion", "Ö6 Reflection", 1, gradingCriterionPointTemplates, AbstractGradingCriterion.Flag.REFLECTION).setFx(false);
return gradingReportTemplateMaster; return gradingReportTemplateMaster;
} }
private GradingReportTemplate getMagisterTemplate(int credits) { private GradingReportTemplate getMagisterTemplate() {
GradingReportTemplate gradingReportTemplateMagister = new GradingReportTemplate(magisterClass, credits); GradingReportTemplate gradingReportTemplateMagister = new GradingReportTemplate(magisterClass,
LocalDate.of(2024, Month.JANUARY, 1));
List<GradingCriterionPointTemplate> gradingCriterionPointTemplates = initPointTemplates(); List<GradingCriterionPointTemplate> gradingCriterionPointTemplates = initPointTemplates();
gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder() gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder()
@ -837,7 +843,8 @@ public class DataInitializer implements Lifecycle {
.description("För 2 poäng krävs dessutom: att oppositionsrapporten ingående och välbalanserat beskriver styrkor och svagheter hos det utvärderade arbetet ur flera aspekter samt att den innehåller tydliga och välmotiverade förslag till förbättringar.") .description("För 2 poäng krävs dessutom: att oppositionsrapporten ingående och välbalanserat beskriver styrkor och svagheter hos det utvärderade arbetet ur flera aspekter samt att den innehåller tydliga och välmotiverade förslag till förbättringar.")
.descriptionEn("For 2 points the following is also required: that the opposition report thoroughly and in a well-balanced way describes from numerous aspects the strengths and weaknesses of the evaluated thesis and that it offers clear and well-motivated suggestions for improvements.") .descriptionEn("For 2 points the following is also required: that the opposition report thoroughly and in a well-balanced way describes from numerous aspects the strengths and weaknesses of the evaluated thesis and that it offers clear and well-motivated suggestions for improvements.")
.build()); .build());
gradingReportTemplateMagister.addIndividualCriterion("Ö1 Oppositionsrapport", "Ö1 Opposition report", 1, gradingCriterionPointTemplates); gradingReportTemplateMagister.addIndividualCriterion("Ö1 Oppositionsrapport", "Ö1 Opposition report", 1, gradingCriterionPointTemplates,
AbstractGradingCriterion.Flag.OPPOSITION);
gradingCriterionPointTemplates = initPointTemplates(); gradingCriterionPointTemplates = initPointTemplates();
gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder() gradingCriterionPointTemplates.add(new GradingCriterionPointTemplate.Builder()
@ -877,7 +884,7 @@ public class DataInitializer implements Lifecycle {
.description("För 1 poäng krävs: att förmåga har uppvisats att reflektera över det genomförda examensarbetet genom individuellt författande av ett reflektionsdokument.") .description("För 1 poäng krävs: att förmåga har uppvisats att reflektera över det genomförda examensarbetet genom individuellt författande av ett reflektionsdokument.")
.descriptionEn("Requirement for 1 point: that the ability to reflect about the thesis work has been demonstrated through the individual writing of a reflection document.") .descriptionEn("Requirement for 1 point: that the ability to reflect about the thesis work has been demonstrated through the individual writing of a reflection document.")
.build()); .build());
gradingReportTemplateMagister.addIndividualCriterion("Ö6 Reflektion", "Ö6 Reflection", 1, gradingCriterionPointTemplates).setFx(false); gradingReportTemplateMagister.addIndividualCriterion("Ö6 Reflektion", "Ö6 Reflection", 1, gradingCriterionPointTemplates, AbstractGradingCriterion.Flag.REFLECTION).setFx(false);
return gradingReportTemplateMagister; return gradingReportTemplateMagister;
} }

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.activityplan; package se.su.dsv.scipro.activityplan;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.checklist.Checklist; import se.su.dsv.scipro.checklist.Checklist;
import se.su.dsv.scipro.checklist.ChecklistTemplate; import se.su.dsv.scipro.checklist.ChecklistTemplate;
import se.su.dsv.scipro.file.ProjectFileUpload; import se.su.dsv.scipro.file.ProjectFileUpload;

View File

@ -4,7 +4,7 @@ import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.checklist.Checklist; import se.su.dsv.scipro.checklist.Checklist;
import se.su.dsv.scipro.checklist.ChecklistAnswerEnum; import se.su.dsv.scipro.checklist.ChecklistAnswerEnum;
import se.su.dsv.scipro.checklist.ChecklistCategory; import se.su.dsv.scipro.checklist.ChecklistCategory;

View File

@ -2,7 +2,7 @@ package se.su.dsv.scipro.activityplan;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.checklist; package se.su.dsv.scipro.checklist;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional @Transactional

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.checklist; package se.su.dsv.scipro.checklist;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional @Transactional

View File

@ -2,7 +2,7 @@ package se.su.dsv.scipro.checklist;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.file; package se.su.dsv.scipro.file;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional @Transactional

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.file; package se.su.dsv.scipro.file;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import java.util.*; import java.util.*;

View File

@ -2,7 +2,7 @@ package se.su.dsv.scipro.file;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.file; package se.su.dsv.scipro.file;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import java.util.*; import java.util.*;

View File

@ -1,7 +1,7 @@
package se.su.dsv.scipro.file; package se.su.dsv.scipro.file;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import jakarta.inject.Inject; import jakarta.inject.Inject;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.finalseminar; package se.su.dsv.scipro.finalseminar;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;

View File

@ -1,7 +1,7 @@
package se.su.dsv.scipro.finalseminar; package se.su.dsv.scipro.finalseminar;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.*; import se.su.dsv.scipro.system.*;
import se.su.dsv.scipro.util.Either; import se.su.dsv.scipro.util.Either;

View File

@ -5,7 +5,7 @@ import com.google.inject.persist.Transactional;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.file.FileReference; import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.file.FileService; import se.su.dsv.scipro.file.FileService;
import se.su.dsv.scipro.misc.DaysService; import se.su.dsv.scipro.misc.DaysService;

View File

@ -5,7 +5,7 @@ import com.google.inject.persist.Transactional;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.file.FileDescription; import se.su.dsv.scipro.file.FileDescription;
import se.su.dsv.scipro.file.FileReference; import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.file.FileService; import se.su.dsv.scipro.file.FileService;

View File

@ -1,7 +1,7 @@
package se.su.dsv.scipro.forum; package se.su.dsv.scipro.forum;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.forum.dataobjects.ForumThread;
public interface AbstractThreadRepository extends JpaRepository<ForumThread, Long>, QueryDslPredicateExecutor<ForumThread> { public interface AbstractThreadRepository extends JpaRepository<ForumThread, Long>, QueryDslPredicateExecutor<ForumThread> {

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.forum; package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.ForumPost; import se.su.dsv.scipro.forum.dataobjects.ForumPost;
import se.su.dsv.scipro.forum.dataobjects.ForumPostReadState; import se.su.dsv.scipro.forum.dataobjects.ForumPostReadState;
import se.su.dsv.scipro.forum.dataobjects.ForumPostReadStateId; import se.su.dsv.scipro.forum.dataobjects.ForumPostReadStateId;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.forum; package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.ForumPost; import se.su.dsv.scipro.forum.dataobjects.ForumPost;
import se.su.dsv.scipro.forum.dataobjects.ForumThread; import se.su.dsv.scipro.forum.dataobjects.ForumThread;
import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.forum.dataobjects.ProjectThread;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.forum; package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.GroupThread; import se.su.dsv.scipro.forum.dataobjects.GroupThread;
import se.su.dsv.scipro.group.Group; import se.su.dsv.scipro.group.Group;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.forum; package se.su.dsv.scipro.forum;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.forum.dataobjects.ProjectThread; import se.su.dsv.scipro.forum.dataobjects.ProjectThread;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;

View File

@ -3,6 +3,7 @@ package se.su.dsv.scipro.grading;
import com.google.inject.Key; import com.google.inject.Key;
import com.google.inject.PrivateModule; import com.google.inject.PrivateModule;
import com.google.inject.name.Names; import com.google.inject.name.Names;
import se.su.dsv.scipro.report.GradingReportServiceImpl;
public class GradingModule extends PrivateModule { public class GradingModule extends PrivateModule {
@Override @Override
@ -29,5 +30,8 @@ public class GradingModule extends PrivateModule {
bind(NationalSubjectCategoryRepository.class).to(NationalSubjectCategoryRepositoryImpl.class); bind(NationalSubjectCategoryRepository.class).to(NationalSubjectCategoryRepositoryImpl.class);
bind(NationalSubjectCategoryService.class).to(NationalSubjectCategoryServiceImpl.class); bind(NationalSubjectCategoryService.class).to(NationalSubjectCategoryServiceImpl.class);
expose(NationalSubjectCategoryService.class); expose(NationalSubjectCategoryService.class);
bind(GradingReportTemplateService.class).to(GradingReportServiceImpl.class);
expose(GradingReportTemplateService.class);
} }
} }

View File

@ -0,0 +1,41 @@
package se.su.dsv.scipro.grading;
import se.su.dsv.scipro.report.DuplicateDateException;
import se.su.dsv.scipro.report.GradingReportTemplate;
import se.su.dsv.scipro.report.ValidDateMustBeInTheFutureException;
import se.su.dsv.scipro.report.NoSuchTemplateException;
import se.su.dsv.scipro.report.TemplateLockedException;
import se.su.dsv.scipro.system.ProjectType;
import java.time.LocalDate;
import java.util.List;
public interface GradingReportTemplateService {
List<ProjectType> getProjectTypes();
GradingReportTemplate getCurrentTemplate(ProjectType projectType);
GradingReportTemplate getTemplate(long templateId);
/**
* Returns the end date of this grading report template.
* End date is specified as the date before another template takes over.
*
* @return the end date of this grading report template, possibly {@code null}
*/
LocalDate getEndDate(GradingReportTemplate gradingReportTemplate);
List<GradingReportTemplate> getUpcomingTemplates(ProjectType projectType);
GradingReportTemplate update(long templateId, GradingReportTemplateUpdate update)
throws
ValidDateMustBeInTheFutureException,
NoSuchTemplateException,
DuplicateDateException,
TemplateLockedException;
GradingReportTemplate create(ProjectType projectType, GradingReportTemplateUpdate update)
throws
ValidDateMustBeInTheFutureException,
DuplicateDateException;
}

View File

@ -0,0 +1,61 @@
package se.su.dsv.scipro.grading;
import jakarta.annotation.Nullable;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
public record GradingReportTemplateUpdate(
LocalDate validFrom,
@Nullable String note,
String failingGrade,
List<GradeLimit> gradeLimits,
List<Criteria> criteria)
{
public GradingReportTemplateUpdate {
Objects.requireNonNull(validFrom, "Valid from must not be null");
Objects.requireNonNull(failingGrade, "Failing grade must not be null");
Objects.requireNonNull(gradeLimits, "Grades must not be null");
Objects.requireNonNull(criteria, "Criteria must not be null");
for (GradeLimit gradeLimit1 : gradeLimits) {
for (GradeLimit gradeLimit2 : gradeLimits) {
if (gradeLimit1 != gradeLimit2 && gradeLimit1.minimumPoints() == gradeLimit2.minimumPoints()) {
throw new IllegalArgumentException("Duplicate minimum points on grades: %s and %s".formatted(
gradeLimit1.grade(),
gradeLimit2.grade()));
}
}
}
}
public record GradeLimit(String grade, int minimumPoints) {
public GradeLimit {
Objects.requireNonNull(grade, "Grade must not be null");
}
}
public record Criteria(
LocalizedString title,
Type type,
int minimumPointsRequiredToPass,
@Nullable Flag flag,
List<Requirement> requirements)
{
public enum Type {THESIS, INDIVIDUAL}
public enum Flag {OPPOSITION, REFLECTION}
public Criteria {
Objects.requireNonNull(title, "Title must not be null");
Objects.requireNonNull(type, "Type must not be null");
Objects.requireNonNull(requirements, "Requirements must not be null");
}
public record Requirement(int points, LocalizedString description) {
public Requirement {
Objects.requireNonNull(description, "Description must not be null");
}
}
}
}

View File

@ -0,0 +1,10 @@
package se.su.dsv.scipro.grading;
import java.util.Objects;
public record LocalizedString(String english, String swedish) {
public LocalizedString {
Objects.requireNonNull(english, "English must not be null");
Objects.requireNonNull(swedish, "Swedish must not be null");
}
}

View File

@ -2,7 +2,7 @@ package se.su.dsv.scipro.group;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.FilteredService; import se.su.dsv.scipro.system.FilteredService;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.integration.activityfinalseminar; package se.su.dsv.scipro.integration.activityfinalseminar;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.finalseminar.FinalSeminar; import se.su.dsv.scipro.finalseminar.FinalSeminar;
import java.util.Optional; import java.util.Optional;

View File

@ -2,7 +2,7 @@ package se.su.dsv.scipro.mail;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject; import jakarta.inject.Inject;

View File

@ -3,8 +3,8 @@ package se.su.dsv.scipro.match;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import org.springframework.data.domain.PageRequest; import se.su.dsv.scipro.system.PageRequest;
import org.springframework.data.domain.Sort; import se.su.dsv.scipro.system.Sort;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.DegreeType; import se.su.dsv.scipro.system.DegreeType;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.match; package se.su.dsv.scipro.match;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional @Transactional

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.match; package se.su.dsv.scipro.match;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.match; package se.su.dsv.scipro.match;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.match.Idea.Status; import se.su.dsv.scipro.match.Idea.Status;
import se.su.dsv.scipro.match.Idea.Type; import se.su.dsv.scipro.match.Idea.Type;
import se.su.dsv.scipro.system.*; import se.su.dsv.scipro.system.*;

View File

@ -9,7 +9,7 @@ import com.querydsl.core.types.dsl.DateTimeExpression;
import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPAExpressions;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.data.dataobjects.Member; import se.su.dsv.scipro.data.dataobjects.Member;
import se.su.dsv.scipro.generalsystemsettings.GeneralSystemSettings; import se.su.dsv.scipro.generalsystemsettings.GeneralSystemSettings;
import se.su.dsv.scipro.generalsystemsettings.GeneralSystemSettingsService; import se.su.dsv.scipro.generalsystemsettings.GeneralSystemSettingsService;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.match; package se.su.dsv.scipro.match;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.GenericService; import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.ResearchArea; import se.su.dsv.scipro.system.ResearchArea;

View File

@ -4,9 +4,9 @@ import com.google.inject.persist.Transactional;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest; import se.su.dsv.scipro.system.PageRequest;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import org.springframework.data.domain.Sort; import se.su.dsv.scipro.system.Sort;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.ResearchArea; import se.su.dsv.scipro.system.ResearchArea;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.match; package se.su.dsv.scipro.match;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;
import java.util.Set; import java.util.Set;

View File

@ -8,7 +8,7 @@ import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.JPQLQuery; import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;
import jakarta.inject.Inject; import jakarta.inject.Inject;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.match; package se.su.dsv.scipro.match;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.GenericService; import se.su.dsv.scipro.system.GenericService;
public interface MatchService extends GenericService<Match, Long> { public interface MatchService extends GenericService<Match, Long> {

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.match; package se.su.dsv.scipro.match;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import jakarta.inject.Inject; import jakarta.inject.Inject;

View File

@ -2,8 +2,8 @@ package se.su.dsv.scipro.match;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.PageRequest; import se.su.dsv.scipro.system.PageRequest;
import org.springframework.data.domain.Sort; import se.su.dsv.scipro.system.Sort;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.Program; import se.su.dsv.scipro.system.Program;
import se.su.dsv.scipro.system.QProgram; import se.su.dsv.scipro.system.QProgram;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.milestones; package se.su.dsv.scipro.milestones;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.milestones.service; package se.su.dsv.scipro.milestones.service;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.milestones.dataobjects.Milestone; import se.su.dsv.scipro.milestones.dataobjects.Milestone;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.milestones.service; package se.su.dsv.scipro.milestones.service;
import org.springframework.data.domain.Sort; import se.su.dsv.scipro.system.Sort;
import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate;
import se.su.dsv.scipro.springdata.SortOrderService; import se.su.dsv.scipro.springdata.SortOrderService;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.milestones.service; package se.su.dsv.scipro.milestones.service;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.project.ProjectStatus; import se.su.dsv.scipro.project.ProjectStatus;

View File

@ -1,7 +1,7 @@
package se.su.dsv.scipro.milestones.service.impl; package se.su.dsv.scipro.milestones.service.impl;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.domain.Sort; import se.su.dsv.scipro.system.Sort;
import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate;
import se.su.dsv.scipro.milestones.dataobjects.QMilestonePhaseTemplate; import se.su.dsv.scipro.milestones.dataobjects.QMilestonePhaseTemplate;
import se.su.dsv.scipro.milestones.service.MilestonePhaseTemplateService; import se.su.dsv.scipro.milestones.service.MilestonePhaseTemplateService;

View File

@ -4,7 +4,7 @@ import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.milestones.dataobjects.Milestone; import se.su.dsv.scipro.milestones.dataobjects.Milestone;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
import se.su.dsv.scipro.milestones.dataobjects.QMilestone; import se.su.dsv.scipro.milestones.dataobjects.QMilestone;

View File

@ -8,8 +8,8 @@ import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringPath; import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import org.springframework.data.domain.Sort; import se.su.dsv.scipro.system.Sort;
import se.su.dsv.scipro.milestones.dataobjects.Milestone; import se.su.dsv.scipro.milestones.dataobjects.Milestone;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
import se.su.dsv.scipro.milestones.dataobjects.QMilestone; import se.su.dsv.scipro.milestones.dataobjects.QMilestone;

View File

@ -3,7 +3,7 @@ package se.su.dsv.scipro.notifications;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.notifications.dataobject.Notification; import se.su.dsv.scipro.notifications.dataobject.Notification;
import se.su.dsv.scipro.notifications.dataobject.NotificationEvent; import se.su.dsv.scipro.notifications.dataobject.NotificationEvent;
import se.su.dsv.scipro.notifications.dataobject.QNotification; import se.su.dsv.scipro.notifications.dataobject.QNotification;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.peer; package se.su.dsv.scipro.peer;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional @Transactional

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.peer; package se.su.dsv.scipro.peer;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
@Transactional @Transactional
public interface PeerRequestRepository extends JpaRepository<PeerRequest, Long>, QueryDslPredicateExecutor<PeerRequest> { public interface PeerRequestRepository extends JpaRepository<PeerRequest, Long>, QueryDslPredicateExecutor<PeerRequest> {

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.peer; package se.su.dsv.scipro.peer;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.*; import se.su.dsv.scipro.system.*;

View File

@ -4,7 +4,7 @@ import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.file.FileReference; import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.file.FileService; import se.su.dsv.scipro.file.FileService;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;

View File

@ -1,7 +1,7 @@
package se.su.dsv.scipro.peer; package se.su.dsv.scipro.peer;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.peer; package se.su.dsv.scipro.peer;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.*; import se.su.dsv.scipro.system.*;

View File

@ -3,7 +3,7 @@ package se.su.dsv.scipro.peer;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.Language; import se.su.dsv.scipro.system.Language;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.plagiarism; package se.su.dsv.scipro.plagiarism;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.file.FileDescription; import se.su.dsv.scipro.file.FileDescription;
import java.util.Optional; import java.util.Optional;

View File

@ -1,8 +1,8 @@
package se.su.dsv.scipro.project; package se.su.dsv.scipro.project;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;
import java.util.Collection; import java.util.Collection;

View File

@ -5,7 +5,7 @@ import com.google.inject.persist.Transactional;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.data.dataobjects.Member; import se.su.dsv.scipro.data.dataobjects.Member;
import se.su.dsv.scipro.reusable.SciProUtilities; import se.su.dsv.scipro.reusable.SciProUtilities;
import se.su.dsv.scipro.system.AbstractServiceImpl; import se.su.dsv.scipro.system.AbstractServiceImpl;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.projectpartner; package se.su.dsv.scipro.projectpartner;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.match.ApplicationPeriod; import se.su.dsv.scipro.match.ApplicationPeriod;
import se.su.dsv.scipro.system.GenericService; import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;

View File

@ -3,7 +3,7 @@ package se.su.dsv.scipro.projectpartner;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPAExpressions;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.match.ApplicationPeriod; import se.su.dsv.scipro.match.ApplicationPeriod;
import se.su.dsv.scipro.match.QIdea; import se.su.dsv.scipro.match.QIdea;
import se.su.dsv.scipro.match.QIdeaParticipation; import se.su.dsv.scipro.match.QIdeaParticipation;

View File

@ -1,17 +1,42 @@
package se.su.dsv.scipro.report; package se.su.dsv.scipro.report;
import jakarta.persistence.Basic; import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.MappedSuperclass; import jakarta.persistence.MappedSuperclass;
@MappedSuperclass @MappedSuperclass
public abstract class AbstractGradingCriterion extends AbstractCriterion { public abstract class AbstractGradingCriterion extends AbstractCriterion {
public enum Flag {
/**
* Criterion marked with this flag will add extra functionality related
* to the authors submitted reflection. It should only be used on
* individual criteria.
*/
REFLECTION,
/**
* Criterion marked with this flag will add extra functionality related
* to the authors performed opposition. For example, it will have its
* points and feedback filled in when the seminar supervisor assesses
* their opposition and submitted report. It should only be used on
* individual criteria.
*/
OPPOSITION
}
@Basic(optional = false) @Basic(optional = false)
protected int pointsRequiredToPass; protected int pointsRequiredToPass;
@Basic @Basic
private boolean fx = true; private boolean fx = true;
@Basic
@Column(name = "flag")
@Enumerated(EnumType.STRING)
private Flag flag;
protected AbstractGradingCriterion() { protected AbstractGradingCriterion() {
} }
@ -21,6 +46,17 @@ public abstract class AbstractGradingCriterion extends AbstractCriterion {
this.pointsRequiredToPass = pointsRequiredToPass; this.pointsRequiredToPass = pointsRequiredToPass;
} }
protected AbstractGradingCriterion(
String title,
String titleEn,
Integer sortOrder,
int pointsRequiredToPass,
Flag flag)
{
this(title, titleEn, sortOrder, pointsRequiredToPass);
this.flag = flag;
}
public abstract boolean isProjectCriterion(); public abstract boolean isProjectCriterion();
public abstract boolean isIndividualCriterion(); public abstract boolean isIndividualCriterion();
@ -35,6 +71,14 @@ public abstract class AbstractGradingCriterion extends AbstractCriterion {
return this.fx; return this.fx;
} }
public Flag getFlag() {
return flag;
}
public void setFlag(Flag flag) {
this.flag = flag;
}
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o == this) return true; if (o == this) return true;

View File

@ -0,0 +1,23 @@
package se.su.dsv.scipro.report;
import se.su.dsv.scipro.system.ProjectType;
import java.time.LocalDate;
public class DuplicateDateException extends Exception {
private final LocalDate validFrom;
private final ProjectType projectType;
public DuplicateDateException(LocalDate validFrom, ProjectType projectType) {
this.validFrom = validFrom;
this.projectType = projectType;
}
public LocalDate validFrom() {
return validFrom;
}
public ProjectType projectType() {
return projectType;
}
}

View File

@ -1,5 +1,6 @@
package se.su.dsv.scipro.report; package se.su.dsv.scipro.report;
import jakarta.inject.Inject;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.report.calculators.original.SupervisorBachelorGradeCalculator; import se.su.dsv.scipro.report.calculators.original.SupervisorBachelorGradeCalculator;
import se.su.dsv.scipro.report.calculators.original.SupervisorMaster15GradeCalculator; import se.su.dsv.scipro.report.calculators.original.SupervisorMaster15GradeCalculator;
@ -8,8 +9,21 @@ import se.su.dsv.scipro.system.DegreeType;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;
public class GradeCalculatorServiceImpl implements GradeCalculatorService { public class GradeCalculatorServiceImpl implements GradeCalculatorService {
private final GradingReportService gradingReportTemplateService;
@Inject
public GradeCalculatorServiceImpl(GradingReportService gradingReportService) {
this.gradingReportTemplateService = gradingReportService;
}
@Override @Override
public GradeCalculator getSupervisorCalculator(final Project project) { public GradeCalculator getSupervisorCalculator(final Project project) {
GradingReportTemplate template = gradingReportTemplateService.getTemplate(project);
if (!template.getGradeLimits().isEmpty()) {
return new GradingReportTemplateGradeCalculator(template);
}
DegreeType degreeType = project.getProjectType().getDegreeType(); DegreeType degreeType = project.getProjectType().getDegreeType();
if (degreeType == DegreeType.BACHELOR) { if (degreeType == DegreeType.BACHELOR) {
if (getYear(project) >= 2017) { if (getYear(project) >= 2017) {

View File

@ -0,0 +1,46 @@
package se.su.dsv.scipro.report;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "grading_report_template_grade_limits")
public class GradeLimit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "grade")
private String grade;
@Column(name = "lower_limit")
private int lowerLimit;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public int getLowerLimit() {
return lowerLimit;
}
public void setLowerLimit(int lowerLimit) {
this.lowerLimit = lowerLimit;
}
}

View File

@ -30,7 +30,7 @@ public abstract class GradingCriterion extends AbstractGradingCriterion {
} }
GradingCriterion(GradingReport gradingReport, GradingCriterionTemplate gradingCriterionTemplate) { GradingCriterion(GradingReport gradingReport, GradingCriterionTemplate gradingCriterionTemplate) {
super(gradingCriterionTemplate.getTitle(), gradingCriterionTemplate.getTitleEn(), gradingCriterionTemplate.getSortOrder(), gradingCriterionTemplate.getPointsRequiredToPass()); super(gradingCriterionTemplate.getTitle(), gradingCriterionTemplate.getTitleEn(), gradingCriterionTemplate.getSortOrder(), gradingCriterionTemplate.getPointsRequiredToPass(), gradingCriterionTemplate.getFlag());
this.gradingReport = gradingReport; this.gradingReport = gradingReport;
for (GradingCriterionPointTemplate pointTemplate : gradingCriterionTemplate.getGradingCriterionPointTemplates()) { for (GradingCriterionPointTemplate pointTemplate : gradingCriterionTemplate.getGradingCriterionPointTemplates()) {
gradingCriterionPoints.add(new GradingCriterionPoint( gradingCriterionPoints.add(new GradingCriterionPoint(

View File

@ -15,8 +15,14 @@ import java.util.stream.Collectors;
@Entity @Entity
public abstract class GradingReport extends Report { public abstract class GradingReport extends Report {
public enum Grade { public record Grade(String name) {
A, B, C, D, E, F, FX public static final Grade A = new Grade("A");
public static final Grade B = new Grade("B");
public static final Grade C = new Grade("C");
public static final Grade D = new Grade("D");
public static final Grade E = new Grade("E");
public static final Grade F = new Grade("F");
public static final Grade FX = new Grade("FX");
} }
public enum State { INITIAL, REVIEWING, FINALIZED } public enum State { INITIAL, REVIEWING, FINALIZED }

View File

@ -3,14 +3,13 @@ package se.su.dsv.scipro.report;
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition; import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
import se.su.dsv.scipro.grading.GradingBasis; import se.su.dsv.scipro.grading.GradingBasis;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.GenericService;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;
import se.su.dsv.scipro.util.Either; import se.su.dsv.scipro.util.Either;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
public interface GradingReportService extends GenericService<GradingReport, Long> { public interface GradingReportService {
SupervisorGradingReport getSupervisorGradingReport(Project project, User student); SupervisorGradingReport getSupervisorGradingReport(Project project, User student);

View File

@ -2,54 +2,60 @@ package se.su.dsv.scipro.report;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition; import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
import se.su.dsv.scipro.grading.GradingBasis; import se.su.dsv.scipro.grading.GradingBasis;
import se.su.dsv.scipro.grading.GradingReportTemplateService;
import se.su.dsv.scipro.grading.GradingReportTemplateUpdate;
import se.su.dsv.scipro.grading.ThesisSubmissionHistoryService; import se.su.dsv.scipro.grading.ThesisSubmissionHistoryService;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractServiceImpl;
import se.su.dsv.scipro.system.Language; import se.su.dsv.scipro.system.Language;
import se.su.dsv.scipro.system.ProjectModule;
import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.ProjectTypeService;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;
import se.su.dsv.scipro.util.Either; import se.su.dsv.scipro.util.Either;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Provider;
import java.time.Clock; import java.time.Clock;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate;
import java.util.*; import java.util.*;
@Named public class GradingReportServiceImpl implements GradingReportTemplateService, GradingReportService {
public class GradingReportServiceImpl extends AbstractServiceImpl<GradingReport, Long> implements GradingReportService {
public static final String OPPOSITION_SWEDISH = "Ö1 Oppositionsrapport";
public static final String OPPOSITION_ENGLISH = "Ö1 Opposition report";
private final EventBus eventBus; private final EventBus eventBus;
private final ThesisSubmissionHistoryService thesisSubmissionHistoryService; private final ThesisSubmissionHistoryService thesisSubmissionHistoryService;
private final Clock clock; private final Clock clock;
private final SupervisorGradingReportRepository supervisorGradingReportRepository;
private final GradingReportTemplateRepo gradingReportTemplateRepo;
private final ProjectTypeService projectTypeService;
@Inject @Inject
public GradingReportServiceImpl( public GradingReportServiceImpl(
Provider<EntityManager> em,
EventBus eventBus, EventBus eventBus,
ThesisSubmissionHistoryService thesisSubmissionHistoryService, ThesisSubmissionHistoryService thesisSubmissionHistoryService,
Clock clock) Clock clock,
SupervisorGradingReportRepository supervisorGradingReportRepository,
GradingReportTemplateRepo gradingReportTemplateRepo,
ProjectTypeService projectTypeService)
{ {
super(em, GradingReport.class, QGradingReport.gradingReport);
this.eventBus = eventBus; this.eventBus = eventBus;
this.thesisSubmissionHistoryService = thesisSubmissionHistoryService; this.thesisSubmissionHistoryService = thesisSubmissionHistoryService;
this.clock = clock; this.clock = clock;
this.supervisorGradingReportRepository = supervisorGradingReportRepository;
this.gradingReportTemplateRepo = gradingReportTemplateRepo;
this.projectTypeService = projectTypeService;
} }
@Override @Override
public boolean updateOppositionCriteria(SupervisorGradingReport report, FinalSeminarOpposition opposition) { public boolean updateOppositionCriteria(SupervisorGradingReport report, FinalSeminarOpposition opposition) {
for (GradingCriterion gradingCriterion : report.getIndividualCriteria()) { for (GradingCriterion gradingCriterion : report.getIndividualCriteria()) {
boolean isOppositionCriterion = gradingCriterion.getTitle().equals(OPPOSITION_SWEDISH) || gradingCriterion.getTitle().equals(OPPOSITION_ENGLISH); boolean isOppositionCriterion = gradingCriterion.getFlag() == GradingCriterion.Flag.OPPOSITION;
boolean betterGrade = gradingCriterion.getPoints() == null || opposition.getPoints() > gradingCriterion.getPoints(); boolean betterGrade = gradingCriterion.getPoints() == null || opposition.getPoints() > gradingCriterion.getPoints();
if (isOppositionCriterion && betterGrade) { if (isOppositionCriterion && betterGrade) {
gradingCriterion.setFeedback(opposition.getFeedback()); gradingCriterion.setFeedback(opposition.getFeedback());
gradingCriterion.setPoints(opposition.getPoints()); gradingCriterion.setPoints(opposition.getPoints());
save(report); supervisorGradingReportRepository.save(report);
return true; return true;
} }
} }
@ -88,7 +94,7 @@ public class GradingReportServiceImpl extends AbstractServiceImpl<GradingReport,
} }
supervisorGradingReport.setMotivation(gradingBasis.getOverallMotivation()); supervisorGradingReport.setMotivation(gradingBasis.getOverallMotivation());
supervisorGradingReport.setRejectionCommentFeedback(gradingBasis.getRejectionCommentFeedback()); supervisorGradingReport.setRejectionCommentFeedback(gradingBasis.getRejectionCommentFeedback());
save(supervisorGradingReport); supervisorGradingReportRepository.save(supervisorGradingReport);
} }
return getGradingBasis(project); return getGradingBasis(project);
} }
@ -138,22 +144,18 @@ public class GradingReportServiceImpl extends AbstractServiceImpl<GradingReport,
@Override @Override
@Transactional @Transactional
public SupervisorGradingReport getSupervisorGradingReport(Project project, User user) { public SupervisorGradingReport getSupervisorGradingReport(Project project, User user) {
SupervisorGradingReport supervisorGradingReport = from(QSupervisorGradingReport.supervisorGradingReport) SupervisorGradingReport supervisorGradingReport = supervisorGradingReportRepository.getReport(project, user);
.where(QSupervisorGradingReport.supervisorGradingReport.user.eq(user).and(
QSupervisorGradingReport.supervisorGradingReport.project.eq(project)))
.fetchOne();
if (supervisorGradingReport == null) { if (supervisorGradingReport == null) {
supervisorGradingReport = save(getTemplate(project).createSupervisorReport(project, user)); GradingReportTemplate template = getTemplate(project);
SupervisorGradingReport supervisorReport = template.createSupervisorReport(project, user);
supervisorGradingReport = supervisorGradingReportRepository.save(supervisorReport);
} }
return supervisorGradingReport; return supervisorGradingReport;
} }
@Override @Override
public GradingReportTemplate getTemplate(Project project) { public GradingReportTemplate getTemplate(Project project) {
QGradingReportTemplate template = QGradingReportTemplate.gradingReportTemplate; return gradingReportTemplateRepo.getTemplate(project);
return from(template)
.where(template.projectType.eq(project.getProjectType()).and(template.credits.eq(project.getCredits())))
.fetchOne();
} }
@Override @Override
@ -192,11 +194,100 @@ public class GradingReportServiceImpl extends AbstractServiceImpl<GradingReport,
rejectionCommentFeedback); rejectionCommentFeedback);
} }
save(supervisorGradingReport); supervisorGradingReportRepository.save(supervisorGradingReport);
return Either.right(supervisorGradingReport); return Either.right(supervisorGradingReport);
} }
private static boolean isBlank(final String str) { private static boolean isBlank(final String str) {
return str == null || str.isBlank(); return str == null || str.isBlank();
} }
@Override
public List<ProjectType> getProjectTypes() {
return projectTypeService.findWithModule(ProjectModule.GRADING);
}
@Override
public GradingReportTemplate getCurrentTemplate(ProjectType projectType) {
return gradingReportTemplateRepo.getCurrentTemplate(projectType, LocalDate.now(clock));
}
@Override
public GradingReportTemplate getTemplate(long templateId) {
return gradingReportTemplateRepo.findOne(templateId);
}
@Override
public LocalDate getEndDate(GradingReportTemplate gradingReportTemplate) {
GradingReportTemplate next = gradingReportTemplateRepo.getNextTemplate(gradingReportTemplate);
if (next == null) {
return null;
} else {
return next.getValidFrom().minusDays(1);
}
}
@Override
public List<GradingReportTemplate> getUpcomingTemplates(ProjectType projectType) {
GradingReportTemplate current = getCurrentTemplate(projectType);
if (current == null) {
return gradingReportTemplateRepo.getTemplatesValidAfter(projectType, LocalDate.now(clock));
} else {
return gradingReportTemplateRepo.getTemplatesValidAfter(projectType, current.getValidFrom());
}
}
@Override
public GradingReportTemplate update(long templateId, GradingReportTemplateUpdate update)
throws ValidDateMustBeInTheFutureException,
NoSuchTemplateException,
DuplicateDateException,
TemplateLockedException
{
LocalDate today = LocalDate.now(clock);
if (!update.validFrom().isAfter(today)) {
throw new ValidDateMustBeInTheFutureException(update.validFrom(), today.plusDays(1));
}
GradingReportTemplate template = gradingReportTemplateRepo.getTemplateById(templateId);
if (template == null) {
throw new NoSuchTemplateException();
}
GradingReportTemplate currentTemplate = gradingReportTemplateRepo.getCurrentTemplate(
template.getProjectType(),
update.validFrom());
if (currentTemplate.getId() != templateId &&
Objects.equals(currentTemplate.getValidFrom(), update.validFrom()))
{
throw new DuplicateDateException(update.validFrom(), template.getProjectType());
}
if (!template.getValidFrom().isAfter(today)) {
throw new TemplateLockedException(template.getValidFrom());
}
return gradingReportTemplateRepo.updateTemplate(templateId, update);
}
@Override
public GradingReportTemplate create(ProjectType projectType, GradingReportTemplateUpdate update)
throws ValidDateMustBeInTheFutureException, DuplicateDateException
{
LocalDate today = LocalDate.now(clock);
if (!update.validFrom().isAfter(today)) {
throw new ValidDateMustBeInTheFutureException(update.validFrom(), today.plusDays(1));
}
GradingReportTemplate currentTemplate = gradingReportTemplateRepo.getCurrentTemplate(
projectType,
update.validFrom());
if (currentTemplate != null &&
Objects.equals(currentTemplate.getValidFrom(), update.validFrom()))
{
throw new DuplicateDateException(update.validFrom(), projectType);
}
return gradingReportTemplateRepo.createTemplate(projectType, update);
}
} }

View File

@ -7,6 +7,9 @@ import se.su.dsv.scipro.system.ProjectType;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;
import jakarta.persistence.*; import jakarta.persistence.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -23,22 +26,35 @@ public class GradingReportTemplate extends DomainObject {
@OneToOne(optional = false) @OneToOne(optional = false)
private ProjectType projectType; private ProjectType projectType;
@OneToMany(mappedBy = "gradingReportTemplate", cascade = {CascadeType.ALL}) @OneToMany(mappedBy = "gradingReportTemplate", cascade = {CascadeType.ALL}, orphanRemoval = true)
private Collection<GradingCriterionTemplate> criteria = new HashSet<>(); private Collection<GradingCriterionTemplate> criteria = new HashSet<>();
@Temporal(TemporalType.DATE)
@Column(name = "valid_from")
private LocalDate validFrom;
@Basic @Basic
private int credits; @Column(name = "note")
private String note;
@Basic
@Column(name = "failing_grade")
private String failingGrade;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "grading_report_template_id")
private Collection<GradeLimit> gradeLimits = new ArrayList<>();
protected GradingReportTemplate() { protected GradingReportTemplate() {
} }
public GradingReportTemplate(ProjectType projectType, int credits) { public GradingReportTemplate(ProjectType projectType, LocalDate validFrom) {
if (projectType == null) { if (projectType == null) {
throw new IllegalArgumentException("ProjectType may not be null"); throw new IllegalArgumentException("ProjectType may not be null");
} }
this.projectType = projectType; this.projectType = projectType;
this.credits = credits; this.validFrom = validFrom;
} }
public SupervisorGradingReport createSupervisorReport(Project project, User student) { public SupervisorGradingReport createSupervisorReport(Project project, User student) {
@ -53,18 +69,28 @@ public class GradingReportTemplate extends DomainObject {
} }
public GradingCriterionTemplate addProjectCriterion(String title, String titleEn, int pointsRequiredToPass, List<GradingCriterionPointTemplate> gradingCriterionPointTemplates) { public GradingCriterionTemplate addProjectCriterion(String title, String titleEn, int pointsRequiredToPass, List<GradingCriterionPointTemplate> gradingCriterionPointTemplates) {
return addProjectCriterion(title, titleEn, pointsRequiredToPass, gradingCriterionPointTemplates, null);
}
public GradingCriterionTemplate addProjectCriterion(String title, String titleEn, int pointsRequiredToPass, List<GradingCriterionPointTemplate> gradingCriterionPointTemplates, AbstractGradingCriterion.Flag flag) {
GradingCriterionTemplate gradingCriterionTemplate = new ProjectGradingCriterionTemplate(this, criteria.size(), title, titleEn, pointsRequiredToPass, gradingCriterionPointTemplates); GradingCriterionTemplate gradingCriterionTemplate = new ProjectGradingCriterionTemplate(this, criteria.size(), title, titleEn, pointsRequiredToPass, gradingCriterionPointTemplates);
gradingCriterionTemplate.setFlag(flag);
criteria.add(gradingCriterionTemplate); criteria.add(gradingCriterionTemplate);
return gradingCriterionTemplate; return gradingCriterionTemplate;
} }
public GradingCriterionTemplate addIndividualCriterion(String title, String titleEn, int pointsRequiredToPass, List<GradingCriterionPointTemplate> gradingCriterionPointTemplates) { public GradingCriterionTemplate addIndividualCriterion(String title, String titleEn, int pointsRequiredToPass, List<GradingCriterionPointTemplate> gradingCriterionPointTemplates) {
return addIndividualCriterion(title, titleEn, pointsRequiredToPass, gradingCriterionPointTemplates, null);
}
public GradingCriterionTemplate addIndividualCriterion(String title, String titleEn, int pointsRequiredToPass, List<GradingCriterionPointTemplate> gradingCriterionPointTemplates, AbstractGradingCriterion.Flag flag) {
GradingCriterionTemplate gradingCriterionTemplate = new IndividualGradingCriterionTemplate(this, criteria.size(), title, titleEn, pointsRequiredToPass, gradingCriterionPointTemplates); GradingCriterionTemplate gradingCriterionTemplate = new IndividualGradingCriterionTemplate(this, criteria.size(), title, titleEn, pointsRequiredToPass, gradingCriterionPointTemplates);
gradingCriterionTemplate.setFlag(flag);
criteria.add(gradingCriterionTemplate); criteria.add(gradingCriterionTemplate);
return gradingCriterionTemplate; return gradingCriterionTemplate;
} }
public Iterable<GradingCriterionTemplate> getCriteria() { public Collection<GradingCriterionTemplate> getCriteria() {
return criteria; return criteria;
} }
@ -73,6 +99,46 @@ public class GradingReportTemplate extends DomainObject {
return this.id; return this.id;
} }
public LocalDate getValidFrom() {
return validFrom;
}
public void setValidFrom(LocalDate validFrom) {
this.validFrom = validFrom;
}
public ProjectType getProjectType() {
return projectType;
}
public void setProjectType(ProjectType projectType) {
this.projectType = projectType;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getFailingGrade() {
return failingGrade;
}
public void setFailingGrade(String failingGrade) {
this.failingGrade = failingGrade;
}
public Collection<GradeLimit> getGradeLimits() {
return gradeLimits;
}
public void setGradeLimits(Collection<GradeLimit> gradeLimits) {
this.gradeLimits = gradeLimits;
}
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (o == this) return true; if (o == this) return true;
@ -93,6 +159,6 @@ public class GradingReportTemplate extends DomainObject {
@Override @Override
public String toString() { public String toString() {
return "GradingReportTemplate(id=" + this.id + ", projectType=" + this.projectType + ", credits=" + this.credits + ")"; return "GradingReportTemplate(id=" + this.id + ", projectType=" + this.projectType + ", validFrom=" + this.validFrom + ")";
} }
} }

View File

@ -0,0 +1,39 @@
package se.su.dsv.scipro.report;
import java.util.Comparator;
import java.util.Objects;
class GradingReportTemplateGradeCalculator implements GradeCalculator {
private final GradingReportTemplate template;
GradingReportTemplateGradeCalculator(GradingReportTemplate template) {
this.template = template;
}
@Override
public GradingReport.Grade getGrade(GradingReport gradingReport) {
for (GradingCriterion gradingCriterion : gradingReport.getGradingCriteria()) {
if (!gradingCriterion.meetsMinimumPointRequirement()) {
return new GradingReport.Grade(template.getFailingGrade());
}
}
long points = getPoints(gradingReport);
String textualGrade = template.getGradeLimits()
.stream()
.filter(gradeLimit -> points >= gradeLimit.getLowerLimit())
.max(Comparator.comparing(GradeLimit::getLowerLimit))
.map(GradeLimit::getGrade)
.orElseGet(template::getFailingGrade);
return new GradingReport.Grade(textualGrade);
}
@Override
public long getPoints(GradingReport gradingReport) {
return gradingReport.getGradingCriteria()
.stream()
.map(GradingCriterion::getPoints)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
}
}

View File

@ -1,8 +1,25 @@
package se.su.dsv.scipro.report; package se.su.dsv.scipro.report;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.grading.GradingReportTemplateUpdate;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.ProjectType; import se.su.dsv.scipro.system.ProjectType;
import java.time.LocalDate;
import java.util.List;
public interface GradingReportTemplateRepo extends JpaRepository<GradingReportTemplate, Long> { public interface GradingReportTemplateRepo extends JpaRepository<GradingReportTemplate, Long> {
GradingReportTemplate findByProjectTypeAndCredits(ProjectType projectType, int credits); GradingReportTemplate getTemplate(Project project);
GradingReportTemplate getCurrentTemplate(ProjectType projectType, LocalDate now);
GradingReportTemplate getNextTemplate(GradingReportTemplate gradingReportTemplate);
List<GradingReportTemplate> getTemplatesValidAfter(ProjectType projectType, LocalDate date);
GradingReportTemplate getTemplateById(long templateId);
GradingReportTemplate updateTemplate(long templateId, GradingReportTemplateUpdate update);
GradingReportTemplate createTemplate(ProjectType projectType, GradingReportTemplateUpdate update);
} }

View File

@ -1,12 +1,19 @@
package se.su.dsv.scipro.report; package se.su.dsv.scipro.report;
import com.google.inject.persist.Transactional;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.JPQLQuery;
import se.su.dsv.scipro.grading.GradingReportTemplateUpdate;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.GenericRepo; import se.su.dsv.scipro.system.GenericRepo;
import se.su.dsv.scipro.system.ProjectType;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import jakarta.inject.Provider; import jakarta.inject.Provider;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery; import se.su.dsv.scipro.system.ProjectType;
import java.time.LocalDate;
import java.util.List;
public class GradingReportTemplateRepoImpl extends GenericRepo<GradingReportTemplate, Long> implements GradingReportTemplateRepo { public class GradingReportTemplateRepoImpl extends GenericRepo<GradingReportTemplate, Long> implements GradingReportTemplateRepo {
@Inject @Inject
@ -15,10 +22,114 @@ public class GradingReportTemplateRepoImpl extends GenericRepo<GradingReportTemp
} }
@Override @Override
public GradingReportTemplate findByProjectTypeAndCredits(ProjectType projectType, int credits) { public GradingReportTemplate getTemplate(Project project) {
TypedQuery<GradingReportTemplate> query = em().createQuery("select distinct template from GradingReportTemplate template where template.projectType = :projectType and template.credits = :credits", GradingReportTemplate.class); return getCurrentTemplate(project.getProjectType(), project.getStartDate());
query.setParameter("projectType", projectType); }
query.setParameter("credits", credits);
return query.getSingleResult(); @Override
public GradingReportTemplate getCurrentTemplate(ProjectType projectType, LocalDate now) {
QGradingReportTemplate template = QGradingReportTemplate.gradingReportTemplate;
// find the latest template that is valid for the project
JPQLQuery<LocalDate> validFrom = JPAExpressions
.select(template.validFrom.max())
.from(template)
.where(template.projectType.eq(projectType)
.and(template.validFrom.loe(now)));
return findOne(template.projectType.eq(projectType).and(template.validFrom.eq(validFrom)));
}
@Override
public GradingReportTemplate getNextTemplate(GradingReportTemplate gradingReportTemplate) {
QGradingReportTemplate template = QGradingReportTemplate.gradingReportTemplate;
// find the latest template that is valid for the project
JPQLQuery<LocalDate> validFrom = JPAExpressions
.select(template.validFrom.min())
.from(template)
.where(template.projectType.eq(gradingReportTemplate.getProjectType())
.and(template.validFrom.gt(gradingReportTemplate.getValidFrom())));
return findOne(template.projectType.eq(gradingReportTemplate.getProjectType()).and(template.validFrom.eq(validFrom)));
}
@Override
public List<GradingReportTemplate> getTemplatesValidAfter(ProjectType projectType, LocalDate date) {
return findAll(QGradingReportTemplate.gradingReportTemplate.projectType.eq(projectType)
.and(QGradingReportTemplate.gradingReportTemplate.validFrom.gt(date)));
}
@Override
public GradingReportTemplate getTemplateById(long templateId) {
return findOne(templateId);
}
@Override
@Transactional
public GradingReportTemplate updateTemplate(long templateId, GradingReportTemplateUpdate update) {
GradingReportTemplate gradingReportTemplate = findOne(templateId);
return updateTemplate(gradingReportTemplate, update);
}
private GradingReportTemplate updateTemplate(
GradingReportTemplate gradingReportTemplate,
GradingReportTemplateUpdate update)
{
gradingReportTemplate.setValidFrom(update.validFrom());
gradingReportTemplate.setNote(update.note());
gradingReportTemplate.setFailingGrade(update.failingGrade());
gradingReportTemplate.getCriteria().clear();
for (var criteria : update.criteria()) {
final List<GradingCriterionPointTemplate> pointTemplates = criteria.requirements()
.stream()
.map(this::toPointTemplate)
.toList();
AbstractGradingCriterion.Flag flag = criteria.flag() == null ? null : switch (criteria.flag()) {
case OPPOSITION -> AbstractGradingCriterion.Flag.OPPOSITION;
case REFLECTION -> AbstractGradingCriterion.Flag.REFLECTION;
//case null -> null; sigh java 17
};
switch (criteria.type()) {
case THESIS -> {
gradingReportTemplate.addProjectCriterion(
criteria.title().swedish(),
criteria.title().english(),
criteria.minimumPointsRequiredToPass(),
pointTemplates,
flag);
}
case INDIVIDUAL -> {
gradingReportTemplate.addIndividualCriterion(
criteria.title().swedish(),
criteria.title().english(),
criteria.minimumPointsRequiredToPass(),
pointTemplates,
flag);
}
}
}
gradingReportTemplate.getGradeLimits().clear();
for (var grade : update.gradeLimits()) {
GradeLimit gradeLimit = new GradeLimit();
gradeLimit.setGrade(grade.grade());
gradeLimit.setLowerLimit(grade.minimumPoints());
gradingReportTemplate.getGradeLimits().add(gradeLimit);
}
return save(gradingReportTemplate);
}
@Override
@Transactional
public GradingReportTemplate createTemplate(ProjectType projectType, GradingReportTemplateUpdate update) {
GradingReportTemplate gradingReportTemplate = new GradingReportTemplate(projectType, update.validFrom());
return updateTemplate(gradingReportTemplate, update);
}
private GradingCriterionPointTemplate toPointTemplate(GradingReportTemplateUpdate.Criteria.Requirement requirement) {
return new GradingCriterionPointTemplate.Builder()
.point(requirement.points())
.description(requirement.description().swedish())
.descriptionEn(requirement.description().english())
.build();
} }
} }

View File

@ -0,0 +1,4 @@
package se.su.dsv.scipro.report;
public class NoSuchTemplateException extends Exception {
}

View File

@ -1,7 +1,7 @@
package se.su.dsv.scipro.report; package se.su.dsv.scipro.report;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor; import se.su.dsv.scipro.system.QueryDslPredicateExecutor;
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition; import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
public interface OppositionReportRepo extends JpaRepository<OppositionReport, Long>, QueryDslPredicateExecutor<OppositionReport> { public interface OppositionReportRepo extends JpaRepository<OppositionReport, Long>, QueryDslPredicateExecutor<OppositionReport> {

View File

@ -33,7 +33,7 @@ public class OppositionReportServiceImpl implements OppositionReportService {
if (oppositionReport != null) { if (oppositionReport != null) {
return oppositionReport; return oppositionReport;
} else { } else {
OppositionReport newReport = gradingReportTemplateRepo.findByProjectTypeAndCredits(finalSeminarOpposition.getProjectType(), finalSeminarOpposition.getProject().getCredits()) OppositionReport newReport = gradingReportTemplateRepo.getTemplate(finalSeminarOpposition.getProject())
.createOppositionReport(finalSeminarOpposition); .createOppositionReport(finalSeminarOpposition);
return oppositionReportRepo.save(newReport); return oppositionReportRepo.save(newReport);
} }

View File

@ -0,0 +1,10 @@
package se.su.dsv.scipro.report;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.User;
public interface SupervisorGradingReportRepository {
SupervisorGradingReport save(SupervisorGradingReport report);
SupervisorGradingReport getReport(Project project, User author);
}

View File

@ -0,0 +1,37 @@
package se.su.dsv.scipro.report;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.persistence.EntityManager;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.AbstractRepository;
import se.su.dsv.scipro.system.User;
public class SupervisorGradingReportRepositoryImpl extends AbstractRepository
implements SupervisorGradingReportRepository
{
@Inject
public SupervisorGradingReportRepositoryImpl(Provider<EntityManager> em) {
super(em);
}
@Override
public SupervisorGradingReport save(SupervisorGradingReport report) {
EntityManager entityManager = em();
if (entityManager.contains(report)) {
return entityManager.merge(report);
}
else {
entityManager.persist(report);
return report;
}
}
@Override
public SupervisorGradingReport getReport(Project project, User author) {
return from(QSupervisorGradingReport.supervisorGradingReport)
.where(QSupervisorGradingReport.supervisorGradingReport.user.eq(author).and(
QSupervisorGradingReport.supervisorGradingReport.project.eq(project)))
.fetchOne();
}
}

View File

@ -0,0 +1,15 @@
package se.su.dsv.scipro.report;
import java.time.LocalDate;
public class TemplateLockedException extends Exception {
private final LocalDate becameValidAt;
public TemplateLockedException(LocalDate becameValidAt) {
this.becameValidAt = becameValidAt;
}
public LocalDate becameValidAt() {
return becameValidAt;
}
}

View File

@ -0,0 +1,21 @@
package se.su.dsv.scipro.report;
import java.time.LocalDate;
public class ValidDateMustBeInTheFutureException extends Exception {
private final LocalDate validFrom;
private final LocalDate earliestAllowedValidFrom;
public ValidDateMustBeInTheFutureException(LocalDate validFrom, LocalDate earliestAllowedValidFrom) {
this.validFrom = validFrom;
this.earliestAllowedValidFrom = earliestAllowedValidFrom;
}
public LocalDate validFrom() {
return validFrom;
}
public LocalDate earliestAllowedValidFrom() {
return earliestAllowedValidFrom;
}
}

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.reviewing; package se.su.dsv.scipro.reviewing;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.project.ProjectStatus; import se.su.dsv.scipro.project.ProjectStatus;
import se.su.dsv.scipro.system.GenericService; import se.su.dsv.scipro.system.GenericService;

View File

@ -7,7 +7,7 @@ import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringPath; import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.finalseminar.QFinalSeminar; import se.su.dsv.scipro.finalseminar.QFinalSeminar;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.project.ProjectStatus; import se.su.dsv.scipro.project.ProjectStatus;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.reviewing; package se.su.dsv.scipro.reviewing;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.forum.dataobjects.ReviewerThread; import se.su.dsv.scipro.forum.dataobjects.ReviewerThread;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;

View File

@ -3,7 +3,7 @@ package se.su.dsv.scipro.springdata.serviceimpls;
import com.querydsl.core.BooleanBuilder; import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.JPAExpressions;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.match.ApplicationPeriod; import se.su.dsv.scipro.match.ApplicationPeriod;
import se.su.dsv.scipro.match.QTarget; import se.su.dsv.scipro.match.QTarget;
import se.su.dsv.scipro.security.auth.roles.Roles; import se.su.dsv.scipro.security.auth.roles.Roles;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.springdata.services; package se.su.dsv.scipro.springdata.services;
import org.springframework.data.domain.Pageable; import se.su.dsv.scipro.system.Pageable;
import se.su.dsv.scipro.match.ApplicationPeriod; import se.su.dsv.scipro.match.ApplicationPeriod;
import se.su.dsv.scipro.system.*; import se.su.dsv.scipro.system.*;

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.survey; package se.su.dsv.scipro.survey;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
public interface QuestionRepository extends JpaRepository<Question, Long> { public interface QuestionRepository extends JpaRepository<Question, Long> {
} }

View File

@ -1,6 +1,6 @@
package se.su.dsv.scipro.survey; package se.su.dsv.scipro.survey;
import org.springframework.data.jpa.repository.JpaRepository; import se.su.dsv.scipro.system.JpaRepository;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.User; import se.su.dsv.scipro.system.User;

View File

@ -6,8 +6,6 @@ import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringPath; import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import jakarta.inject.Provider; import jakarta.inject.Provider;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;

View File

@ -1,7 +1,5 @@
package se.su.dsv.scipro.system; package se.su.dsv.scipro.system;
import org.springframework.data.domain.Pageable;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;

View File

@ -1,8 +1,6 @@
package se.su.dsv.scipro.system; package se.su.dsv.scipro.system;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
@Transactional @Transactional
public interface FooterAddressRepo extends JpaRepository<FooterAddress, Long>, QueryDslPredicateExecutor<FooterAddress> { public interface FooterAddressRepo extends JpaRepository<FooterAddress, Long>, QueryDslPredicateExecutor<FooterAddress> {

View File

@ -1,8 +1,6 @@
package se.su.dsv.scipro.system; package se.su.dsv.scipro.system;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;

View File

@ -6,10 +6,6 @@ import com.querydsl.core.types.dsl.EntityPathBase;
import com.querydsl.core.types.dsl.Expressions; import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringPath; import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQuery;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import jakarta.inject.Provider; import jakarta.inject.Provider;
import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManager;

View File

@ -1,7 +1,6 @@
package se.su.dsv.scipro.system; package se.su.dsv.scipro.system;
import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.Pageable;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,4 @@
package org.springframework.data.jpa.repository; package se.su.dsv.scipro.system;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;

View File

@ -1,6 +1,5 @@
package se.su.dsv.scipro.system; package se.su.dsv.scipro.system;
import org.springframework.data.domain.PageRequest;
import se.su.dsv.scipro.security.auth.roles.Roles; import se.su.dsv.scipro.security.auth.roles.Roles;
import jakarta.inject.Inject; import jakarta.inject.Inject;

View File

@ -1,4 +1,4 @@
package org.springframework.data.domain; package se.su.dsv.scipro.system;
import java.util.Objects; import java.util.Objects;

View File

@ -1,4 +1,4 @@
package org.springframework.data.domain; package se.su.dsv.scipro.system;
public interface Pageable { public interface Pageable {
long getOffset(); long getOffset();

View File

@ -1,8 +1,6 @@
package se.su.dsv.scipro.system; package se.su.dsv.scipro.system;
import com.google.inject.persist.Transactional; import com.google.inject.persist.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
@Transactional @Transactional

Some files were not shown because too many files have changed in this diff Show More