diff --git a/core/src/main/java/se/su/dsv/scipro/grading/GradingReportTemplateUpdate.java b/core/src/main/java/se/su/dsv/scipro/grading/GradingReportTemplateUpdate.java index 92fc554904..ce7a1b70aa 100644 --- a/core/src/main/java/se/su/dsv/scipro/grading/GradingReportTemplateUpdate.java +++ b/core/src/main/java/se/su/dsv/scipro/grading/GradingReportTemplateUpdate.java @@ -10,28 +10,28 @@ public record GradingReportTemplateUpdate( LocalDate validFrom, @Nullable String note, String failingGrade, - List<Grade> grades, + 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(grades, "Grades must not be null"); + Objects.requireNonNull(gradeLimits, "Grades must not be null"); Objects.requireNonNull(criteria, "Criteria must not be null"); - for (Grade grade1 : grades) { - for (Grade grade2 : grades) { - if (grade1 != grade2 && grade1.minimumPoints() == grade2.minimumPoints()) { + 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( - grade1.grade(), - grade2.grade())); + gradeLimit1.grade(), + gradeLimit2.grade())); } } } } - public record Grade(String grade, int minimumPoints) { - public Grade { + public record GradeLimit(String grade, int minimumPoints) { + public GradeLimit { Objects.requireNonNull(grade, "Grade must not be null"); } } diff --git a/core/src/main/java/se/su/dsv/scipro/report/GradeLimit.java b/core/src/main/java/se/su/dsv/scipro/report/GradeLimit.java new file mode 100644 index 0000000000..49d6b60097 --- /dev/null +++ b/core/src/main/java/se/su/dsv/scipro/report/GradeLimit.java @@ -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; + } +} diff --git a/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplate.java b/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplate.java index c6aa3a09a3..a4b56f3b1d 100644 --- a/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplate.java +++ b/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplate.java @@ -9,6 +9,7 @@ import se.su.dsv.scipro.system.User; import jakarta.persistence.*; import java.time.LocalDate; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -40,6 +41,10 @@ public class GradingReportTemplate extends DomainObject { @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() { } @@ -116,6 +121,14 @@ public class GradingReportTemplate extends DomainObject { this.failingGrade = failingGrade; } + public Collection<GradeLimit> getGradeLimits() { + return gradeLimits; + } + + public void setGradeLimits(Collection<GradeLimit> gradeLimits) { + this.gradeLimits = gradeLimits; + } + @Override public boolean equals(final Object o) { if (o == this) return true; diff --git a/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplateRepoImpl.java b/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplateRepoImpl.java index d793b7c16e..316b59f515 100644 --- a/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplateRepoImpl.java +++ b/core/src/main/java/se/su/dsv/scipro/report/GradingReportTemplateRepoImpl.java @@ -93,6 +93,14 @@ public class GradingReportTemplateRepoImpl extends GenericRepo<GradingReportTemp } } + 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); } diff --git a/core/src/main/resources/db/migration/V391__grade_limits_on_grading_templates.sql b/core/src/main/resources/db/migration/V391__grade_limits_on_grading_templates.sql new file mode 100644 index 0000000000..80a2cc6439 --- /dev/null +++ b/core/src/main/resources/db/migration/V391__grade_limits_on_grading_templates.sql @@ -0,0 +1,10 @@ +CREATE TABLE `grading_report_template_grade_limits` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `grading_report_template_id` BIGINT, -- can't be NOT NULL because of Hibernate using an INSERT followed by an UPDATE + `grade` VARCHAR(32) NOT NULL, + `lower_limit` INT NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `UK_one_grade_per_template` (`grading_report_template_id`, `grade`), + FOREIGN KEY `FK_grade_limit_grading_report_template `(`grading_report_template_id`) + REFERENCES `grading_report_template` (`id`) ON DELETE CASCADE +); diff --git a/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/AdminGradingTemplateEditPage.java b/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/AdminGradingTemplateEditPage.java index c8ca35b503..3b75b4ce2a 100644 --- a/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/AdminGradingTemplateEditPage.java +++ b/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/AdminGradingTemplateEditPage.java @@ -67,7 +67,7 @@ public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage imple } private GradingReportTemplateUpdate toUpdate(EditingGradingTemplate editingGradingTemplate) { - List<GradingReportTemplateUpdate.Grade> grades = editingGradingTemplate + List<GradingReportTemplateUpdate.GradeLimit> gradeLimits = editingGradingTemplate .getGradeLimits() .getGradeLimits() .stream() @@ -82,7 +82,7 @@ public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage imple editingGradingTemplate.getValidFrom(), editingGradingTemplate.getNote(), editingGradingTemplate.getGradeLimits().getFailingGrade(), - grades, + gradeLimits, criteria); } @@ -117,8 +117,8 @@ public class AdminGradingTemplateEditPage extends AbstractAdminProjectPage imple }; } - private GradingReportTemplateUpdate.Grade toGrade(GradeLimits.GradeLimit gradeLimit) { - return new GradingReportTemplateUpdate.Grade( + private GradingReportTemplateUpdate.GradeLimit toGrade(GradeLimits.GradeLimit gradeLimit) { + return new GradingReportTemplateUpdate.GradeLimit( gradeLimit.getGrade(), gradeLimit.getLowerLimit()); } diff --git a/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/GradeLimits.java b/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/GradeLimits.java index 093455f4d1..cb728abd76 100644 --- a/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/GradeLimits.java +++ b/view/src/main/java/se/su/dsv/scipro/admin/pages/grading/GradeLimits.java @@ -12,6 +12,12 @@ class GradeLimits implements Serializable { GradeLimits(GradingReportTemplate template) { this.gradeLimits = new ArrayList<>(); + for (var gradeLimit : template.getGradeLimits()) { + GradeLimit editableGradeLimit = new GradeLimit(); + editableGradeLimit.setGrade(gradeLimit.getGrade()); + editableGradeLimit.setLowerLimit(gradeLimit.getLowerLimit()); + gradeLimits.add(editableGradeLimit); + } this.failingGrade = template.getFailingGrade(); }