87: Refactor SplittableStatusRecord using Java record

This commit is contained in:
Tom Zhao 2025-04-02 09:41:27 +02:00
parent 8266b1f1fe
commit 1ebf21f14b
5 changed files with 51 additions and 20 deletions
core/src/main/java/se/su/dsv/scipro
view/src
main/java/se/su/dsv/scipro/admin/pages
test/java/se/su/dsv/scipro/admin/pages

@ -816,9 +816,10 @@ public class CoreConfig {
@Bean
public SplitOrRestartProjectServiceImpl SplitOrRestartProjectService(
ProjectService projectService,
FinalSeminarService finalSeminarService
FinalSeminarService finalSeminarService,
RoughDraftApprovalService roughDraftApprovalService
) {
return new SplitOrRestartProjectServiceImpl(projectService, finalSeminarService);
return new SplitOrRestartProjectServiceImpl(projectService, finalSeminarService, roughDraftApprovalService);
}
@Bean

@ -2,13 +2,14 @@ package se.su.dsv.scipro.project.split;
import java.util.List;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.util.Pair;
import se.su.dsv.scipro.reviewing.RoughDraftApproval;
public interface SplitOrRestartProjectService {
enum SplittableStatus {
NOT_EXIST("Project does not exist."),
NOT_ACTIVE("Only active project can be split."),
NOT_TWO_PARTICIPANTS("To be able to split a project, it needs to have 2 participants."),
PHASE_TWO_STARTED("Phase 2 (Review) is already started, can't split right now."),
FINAL_SEMINAR_PHASE_STARTED("Final seminar phase has been started, too late to split."),
OK("Ok to split.");
@ -23,7 +24,13 @@ public interface SplitOrRestartProjectService {
}
}
Pair<SplittableStatus, Project> getSplittableStatus(long projectId);
record SplittableStatusRecord(
SplittableStatus splittableStatus,
Project project,
RoughDraftApproval roughDraftApproval
) {}
SplittableStatusRecord getSplittableStatus(long projectId);
void splitProject(long projectId);

@ -4,11 +4,14 @@ import com.querydsl.core.types.dsl.BooleanExpression;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import java.util.List;
import java.util.Optional;
import se.su.dsv.scipro.finalseminar.FinalSeminarService;
import se.su.dsv.scipro.project.Project;
import se.su.dsv.scipro.project.ProjectService;
import se.su.dsv.scipro.project.ProjectStatus;
import se.su.dsv.scipro.project.QProject;
import se.su.dsv.scipro.reviewing.RoughDraftApproval;
import se.su.dsv.scipro.reviewing.RoughDraftApprovalService;
import se.su.dsv.scipro.system.User;
import se.su.dsv.scipro.util.Pair;
@ -16,47 +19,60 @@ public class SplitOrRestartProjectServiceImpl implements SplitOrRestartProjectSe
private final ProjectService projectService;
private final FinalSeminarService finalSeminarService;
private final RoughDraftApprovalService roughDraftApprovalService;
@Inject
public SplitOrRestartProjectServiceImpl(ProjectService projectService, FinalSeminarService finalSeminarService) {
public SplitOrRestartProjectServiceImpl(
ProjectService projectService,
FinalSeminarService finalSeminarService,
RoughDraftApprovalService roughDraftApprovalService
) {
this.projectService = projectService;
this.finalSeminarService = finalSeminarService;
this.roughDraftApprovalService = roughDraftApprovalService;
}
@Override
@Transactional
public Pair<SplittableStatus, Project> getSplittableStatus(long projectId) {
public SplittableStatusRecord getSplittableStatus(long projectId) {
Project project = projectService.findOne(projectId);
if (project == null) return new Pair<>(SplittableStatus.NOT_EXIST, null);
if (project == null) return new SplittableStatusRecord(SplittableStatus.NOT_EXIST, null, null);
if (project.getProjectStatus() != ProjectStatus.ACTIVE) {
return new Pair<>(SplittableStatus.NOT_ACTIVE, project);
return new SplittableStatusRecord(SplittableStatus.NOT_ACTIVE, project, null);
}
if (project.getProjectParticipants().size() != 2) {
return new Pair<>(SplittableStatus.NOT_TWO_PARTICIPANTS, project);
return new SplittableStatusRecord(SplittableStatus.NOT_TWO_PARTICIPANTS, project, null);
}
if (finalSeminarService.findByProject(project) != null) {
return new Pair<>(SplittableStatus.FINAL_SEMINAR_PHASE_STARTED, project);
return new SplittableStatusRecord(SplittableStatus.FINAL_SEMINAR_PHASE_STARTED, project, null);
}
Optional<RoughDraftApproval> o = roughDraftApprovalService.findBy(project);
if (o.isPresent() && !o.get().isDecided()) {
return new SplittableStatusRecord(SplittableStatus.PHASE_TWO_STARTED, project, null);
}
if (o.isPresent() && o.get().isApproved()) {
return new SplittableStatusRecord(SplittableStatus.OK, project, o.get());
} else {
return new Pair<>(SplittableStatus.OK, project);
return new SplittableStatusRecord(SplittableStatus.OK, project, null);
}
}
@Override
@Transactional
public void splitProject(long projectId) {
Pair<SplittableStatus, Project> result = getSplittableStatus(projectId);
if (result.getHead() != SplittableStatus.OK) {
SplittableStatusRecord result = getSplittableStatus(projectId);
if (result.splittableStatus() != SplittableStatus.OK) {
throw new IllegalStateException(
"Project must to be verified to be able to split " + "before this method can be called."
);
}
Project project = result.getTail();
// Todo: Get ev. Phase Two Approval
Project project = result.project();
for (User author : project.getProjectParticipants()) {
Project childProject = new Project();
@ -81,6 +97,7 @@ public class SplitOrRestartProjectServiceImpl implements SplitOrRestartProjectSe
);
// Todo: add RoughDraftApproval if it's 'APPROVED'
if (result.roughDraftApproval() != null) {}
childProject = projectService.save(childProject);
// Todo: Send event to eventBus to synchronize eventual Phase Two Approval with MileStone

@ -17,7 +17,6 @@ import se.su.dsv.scipro.project.split.SplitOrRestartProjectService;
import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.session.SciProSession;
import se.su.dsv.scipro.util.PageParameterKeys;
import se.su.dsv.scipro.util.Pair;
public class AdminSplitProjectPanel extends Panel {
@ -29,8 +28,9 @@ public class AdminSplitProjectPanel extends Panel {
Project project = projectModel.getObject();
LoadableDetachableModel<SplittableStatus> ldModel = LoadableDetachableModel.of(() -> {
Pair<SplittableStatus, Project> pair = splitOrRestartProjectService.getSplittableStatus(project.getId());
return pair.getHead();
SplitOrRestartProjectService.SplittableStatusRecord status =
splitOrRestartProjectService.getSplittableStatus(project.getId());
return status.splittableStatus();
});
final PageParameters pp = new PageParameters();

@ -273,7 +273,13 @@ public class AdminEditProjectPageTest extends SciProTest {
if (project.getId() != null) when(projectService.findOne(project.getId())).thenReturn(project);
lenient()
.when(splitOrRestartProjectService.getSplittableStatus(project.getId() != null ? project.getId() : 0L))
.thenReturn(new Pair<>(SplitOrRestartProjectService.SplittableStatus.OK, project));
.thenReturn(
new SplitOrRestartProjectService.SplittableStatusRecord(
SplitOrRestartProjectService.SplittableStatus.OK,
project,
null
)
);
PageParameters pp = new PageParameters();
pp.set(PageParameterKeys.MAP.get(Project.class), project.getId());