87: Add clone functionality

This commit is contained in:
Tom Zhao 2025-04-02 12:44:24 +02:00
parent 1ebf21f14b
commit 8a050491f9
5 changed files with 91 additions and 1 deletions
core/src/main

@ -36,6 +36,9 @@ import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
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.DegreeType; import se.su.dsv.scipro.system.DegreeType;
@ -121,6 +124,11 @@ public class Project extends DomainObject {
@Column(name = "root_project_id") @Column(name = "root_project_id")
private Long rootProjectId; private Long rootProjectId;
@Basic
@Column(name = "clone_timestamp")
@Temporal(TemporalType.TIMESTAMP)
private Date cloneTimestamp;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Embedded JPA-mapping // Embedded JPA-mapping
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
@ -389,6 +397,14 @@ public class Project extends DomainObject {
this.rootProjectId = rootProjectId; this.rootProjectId = rootProjectId;
} }
public Date getCloneTimestamp() {
return cloneTimestamp;
}
public void setCloneTimestamp(Date cloneTimestamp) {
this.cloneTimestamp = cloneTimestamp;
}
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Methods Common To All Objects // Methods Common To All Objects
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------

@ -196,6 +196,25 @@ public class Decision {
decideWithDecisionDate(status, reason, attachment, Instant.now()); decideWithDecisionDate(status, reason, attachment, Instant.now());
} }
Decision cloneToReviewerApproval(RoughDraftApproval roughDraftApproval) {
Decision clonedDecision = new Decision();
clonedDecision.reviewerApproval = roughDraftApproval;
clonedDecision.status = this.status;
clonedDecision.reason = this.reason;
clonedDecision.comment = this.comment;
clonedDecision.requested = this.requested;
clonedDecision.decisionDate = this.decisionDate;
clonedDecision.deadline = this.deadline;
clonedDecision.reviewerAssignedAt = this.reviewerAssignedAt;
clonedDecision.assignedReviewer = this.assignedReviewer;
clonedDecision.attachment = this.attachment;
clonedDecision.thesis = this.thesis;
return clonedDecision;
}
private void decideWithDecisionDate( private void decideWithDecisionDate(
final Status status, final Status status,
final String reason, final String reason,

@ -1,6 +1,8 @@
package se.su.dsv.scipro.reviewing; package se.su.dsv.scipro.reviewing;
import jakarta.persistence.Basic;
import jakarta.persistence.CascadeType; import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.DiscriminatorColumn; import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
@ -16,6 +18,9 @@ import java.util.Date;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import se.su.dsv.scipro.file.FileReference; import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.system.DomainObject; import se.su.dsv.scipro.system.DomainObject;
@ -32,6 +37,15 @@ public abstract class ReviewerApproval extends DomainObject {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
@Basic
@Column(name = "is_cloned")
protected Boolean isCloned = false;
@Basic
@Column(name = "clone_timestamp")
@Temporal(TemporalType.TIMESTAMP)
protected Date cloneTimestamp;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// JPA-mappings of foreign keys in this table (reviewer_approval) referencing other // JPA-mappings of foreign keys in this table (reviewer_approval) referencing other
// tables. // tables.
@ -59,6 +73,22 @@ public abstract class ReviewerApproval extends DomainObject {
return this.project; return this.project;
} }
public Boolean getCloned() {
return isCloned;
}
public void setCloned(Boolean cloned) {
isCloned = cloned;
}
public Date getCloneTimestamp() {
return cloneTimestamp;
}
public void setCloneTimestamp(Date cloneDate) {
this.cloneTimestamp = cloneDate;
}
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Other methods // Other methods
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------

@ -1,7 +1,9 @@
package se.su.dsv.scipro.reviewing; package se.su.dsv.scipro.reviewing;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import java.util.*;
import java.time.Instant;
import java.util.Date;
import se.su.dsv.scipro.file.FileReference; import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
@ -24,4 +26,15 @@ public class RoughDraftApproval extends ReviewerApproval {
public Step getStep() { public Step getStep() {
return Step.ROUGH_DRAFT_APPROVAL; return Step.ROUGH_DRAFT_APPROVAL;
} }
public RoughDraftApproval cloneToProject(final Project newProject) {
RoughDraftApproval rda = new RoughDraftApproval();
rda.project = newProject;
this.decisions.forEach(decision -> rda.decisions.add(decision.cloneToReviewerApproval(rda)));
rda.isCloned = true;
rda.cloneTimestamp = Date.from(Instant.now());
return rda;
}
} }

@ -5,6 +5,9 @@ alter table `project`
alter table `project` alter table `project`
add column `root_project_id` bigint(20) null default null; add column `root_project_id` bigint(20) null default null;
alter table `project`
add column `clone_timestamp` datetime not null default null;
alter table `project` alter table `project`
add constraint fk_project_parent_project_id_project_id add constraint fk_project_parent_project_id_project_id
foreign key (parent_project_id) references project(id) foreign key (parent_project_id) references project(id)
@ -14,3 +17,12 @@ alter table `project`
add constraint fk_project_root_project_id_project_id add constraint fk_project_root_project_id_project_id
foreign key (root_project_id) references project(id) foreign key (root_project_id) references project(id)
on delete cascade on update cascade; on delete cascade on update cascade;
alter table `reviewer_approval`
add column `is_cloned` bit(1) not null default false;
alter table `reviewer_approval`
add column `clone_timestamp` datetime not null default null;
update table `reviewer_approval` set is_cloned = false;