Skip to content

Commit

Permalink
Implement archive for okr tool
Browse files Browse the repository at this point in the history
  • Loading branch information
lkleisa committed Mar 25, 2024
1 parent 0df7160 commit 7f3e626
Show file tree
Hide file tree
Showing 18 changed files with 230 additions and 45 deletions.
3 changes: 2 additions & 1 deletion backend/src/main/java/ch/puzzle/okr/dto/ObjectiveDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
import java.time.LocalDateTime;

public record ObjectiveDto(Long id, int version, String title, Long teamId, Long quarterId, String quarterLabel,
String description, State state, LocalDateTime createdOn, LocalDateTime modifiedOn, boolean writeable) {
String description, State state, LocalDateTime createdOn, LocalDateTime modifiedOn, boolean writeable,
boolean archived) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ public ObjectiveDto toDto(Objective objective) {
return new ObjectiveDto(objective.getId(), objective.getVersion(), objective.getTitle(),
objective.getTeam().getId(), objective.getQuarter().getId(), objective.getQuarter().getLabel(),
objective.getDescription(), objective.getState(), objective.getCreatedOn(), objective.getModifiedOn(),
objective.isWriteable());
objective.isWriteable(), objective.isArchived());
}

public Objective toObjective(ObjectiveDto objectiveDto) {
return Objective.Builder.builder().withId(objectiveDto.id()).withVersion(objectiveDto.version())
.withTitle(objectiveDto.title()).withTeam(teamBusinessService.getTeamById(objectiveDto.teamId()))
.withDescription(objectiveDto.description()).withModifiedOn(LocalDateTime.now())
.withState(objectiveDto.state()).withCreatedOn(objectiveDto.createdOn())
.withQuarter(quarterBusinessService.getQuarterById(objectiveDto.quarterId())).build();
.withQuarter(quarterBusinessService.getQuarterById(objectiveDto.quarterId()))
.withArchived(objectiveDto.archived()).build();
}
}
32 changes: 25 additions & 7 deletions backend/src/main/java/ch/puzzle/okr/models/Objective.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public class Objective implements WriteableInterface {
@ManyToOne
private User modifiedBy;

private boolean archived;

private transient boolean writeable;

public Objective() {
Expand All @@ -68,6 +70,7 @@ private Objective(Builder builder) {
setState(builder.state);
setCreatedOn(builder.createdOn);
setModifiedBy(builder.modifiedBy);
setArchived(builder.archived);
}

public Long getId() {
Expand Down Expand Up @@ -150,6 +153,14 @@ public void setModifiedBy(User modifiedBy) {
this.modifiedBy = modifiedBy;
}

public boolean isArchived() {
return archived;
}

public void setArchived(boolean archived) {
this.archived = archived;
}

@Override
public boolean isWriteable() {
return writeable;
Expand All @@ -162,10 +173,10 @@ public void setWriteable(boolean writeable) {

@Override
public String toString() {
return "Objective{" + "id=" + id + ", version=" + version + ", title='" + title + '\'' + ", createdBy="
+ createdBy + ", team=" + team + ", quarter=" + quarter + ", description='" + description + '\''
+ ", modifiedOn=" + modifiedOn + ", state=" + state + ", createdOn=" + createdOn + ", modifiedBy="
+ modifiedBy + ", writeable=" + writeable + '\'' + '}';
return "Objective{" + "id=" + id + ", version=" + version + ", title='" + title + '\'' + ", state=" + state
+ ", description='" + description + '\'' + ", team=" + team + ", quarter=" + quarter + ", createdBy="
+ createdBy + ", createdOn=" + createdOn + ", modifiedOn=" + modifiedOn + ", modifiedBy=" + modifiedBy
+ ", archived=" + archived + ", writeable=" + writeable + '}';
}

@Override
Expand All @@ -180,13 +191,14 @@ public boolean equals(Object o) {
&& Objects.equals(team, objective.team) && Objects.equals(quarter, objective.quarter)
&& Objects.equals(description, objective.description)
&& Objects.equals(modifiedOn, objective.modifiedOn) && state == objective.state
&& Objects.equals(createdOn, objective.createdOn) && Objects.equals(modifiedBy, objective.modifiedBy);
&& Objects.equals(createdOn, objective.createdOn) && Objects.equals(modifiedBy, objective.modifiedBy)
&& Objects.equals(archived, objective.archived);
}

@Override
public int hashCode() {
return Objects.hash(id, version, title, createdBy, team, quarter, description, modifiedOn, state, createdOn,
modifiedBy);
return Objects.hash(id, version, title, state, description, team, quarter, createdBy, createdOn, modifiedOn,
modifiedBy, archived);
}

public static final class Builder {
Expand All @@ -201,6 +213,7 @@ public static final class Builder {
private State state;
private LocalDateTime createdOn;
private User modifiedBy;
private boolean archived;

private Builder() {
}
Expand Down Expand Up @@ -264,6 +277,11 @@ public Builder withModifiedBy(User modifiedBy) {
return this;
}

public Builder withArchived(boolean archived) {
this.archived = archived;
return this;
}

public Objective build() {
return new Objective(this);
}
Expand Down
30 changes: 21 additions & 9 deletions backend/src/main/java/ch/puzzle/okr/models/overview/Overview.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class Overview implements WriteableInterface {
@Enumerated(EnumType.STRING)
private State objectiveState;
private LocalDateTime objectiveCreatedOn;
private boolean objectiveArchived;
private Long quarterId;
private String quarterLabel;
private String keyResultTitle;
Expand Down Expand Up @@ -49,6 +50,7 @@ private Overview(Builder builder) {
objectiveTitle = builder.objectiveTitle;
objectiveState = builder.objectiveState;
objectiveCreatedOn = builder.objectiveCreatedOn;
objectiveArchived = builder.objectiveArchived;
quarterId = builder.quarterId;
quarterLabel = builder.quarterLabel;
keyResultTitle = builder.keyResultTitle;
Expand Down Expand Up @@ -89,6 +91,10 @@ public LocalDateTime getObjectiveCreatedOn() {
return objectiveCreatedOn;
}

public boolean isObjectiveArchived() {
return objectiveArchived;
}

public Long getQuarterId() {
return quarterId;
}
Expand Down Expand Up @@ -157,15 +163,15 @@ public void setWriteable(boolean writeable) {

@Override
public String toString() {
return "Overview{" + "overviewId=" + overviewId + ", teamVersion='" + teamVersion + ", teamName='" + teamName
+ '\'' + ", objectiveTitle='" + objectiveTitle + '\'' + ", objectiveState=" + objectiveState
+ ", objectiveCreatedOn=" + objectiveCreatedOn + ", quarterId=" + quarterId + ", quarterLabel='"
+ quarterLabel + '\'' + ", keyResultTitle='" + keyResultTitle + '\'' + ", keyResultType='"
+ keyResultType + '\'' + ", baseline=" + baseline + ", stretchGoal=" + stretchGoal + ", unit='" + unit
+ '\'' + ", commitZone='" + commitZone + '\'' + ", targetZone='" + targetZone + '\'' + ", stretchZone='"
+ stretchZone + '\'' + ", checkInValue=" + checkInValue + ", checkInZone='" + checkInZone + '\''
+ ", confidence=" + confidence + ", createdOn=" + checkInCreatedOn + ", writeable=" + writeable + '\''
+ '}';
return "Overview{" + "overviewId=" + overviewId + ", teamName='" + teamName + '\'' + ", teamVersion="
+ teamVersion + ", objectiveTitle='" + objectiveTitle + '\'' + ", objectiveState=" + objectiveState
+ ", objectiveCreatedOn=" + objectiveCreatedOn + ", objectiveArchived=" + objectiveArchived
+ ", quarterId=" + quarterId + ", quarterLabel='" + quarterLabel + '\'' + ", keyResultTitle='"
+ keyResultTitle + '\'' + ", keyResultType='" + keyResultType + '\'' + ", baseline=" + baseline
+ ", stretchGoal=" + stretchGoal + ", unit='" + unit + '\'' + ", commitZone='" + commitZone + '\''
+ ", targetZone='" + targetZone + '\'' + ", stretchZone='" + stretchZone + '\'' + ", checkInValue="
+ checkInValue + ", checkInZone='" + checkInZone + '\'' + ", confidence=" + confidence
+ ", checkInCreatedOn=" + checkInCreatedOn + ", writeable=" + writeable + '}';
}

public static final class Builder {
Expand All @@ -175,6 +181,7 @@ public static final class Builder {
private String objectiveTitle;
private State objectiveState;
private LocalDateTime objectiveCreatedOn;
private boolean objectiveArchived;
private Long quarterId;
private String quarterLabel;
private String keyResultTitle;
Expand Down Expand Up @@ -227,6 +234,11 @@ public Builder withObjectiveCreatedOn(LocalDateTime objectiveCreatedOn) {
return this;
}

public Builder withObjectiveArchived(boolean objectiveArchived) {
this.objectiveArchived = objectiveArchived;
return this;
}

public Builder withQuarterId(Long quarterId) {
this.quarterId = quarterId;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ public KeyResultAuthorizationService(KeyResultBusinessService keyResultBusinessS
super(keyResultBusinessService, authorizationService);
}

@Override
public KeyResult getEntityById(Long id) {
AuthorizationUser authorizationUser = getAuthorizationService().getAuthorizationUser();
hasRoleReadById(id, authorizationUser);
KeyResult keyResult = getBusinessService().getEntityById(id);
if (!keyResult.getObjective().isArchived()) {
keyResult.setWriteable(isWriteable(keyResult, authorizationUser));
}
return keyResult;
}

@Override
protected void hasRoleReadById(Long id, AuthorizationUser authorizationUser) {
getAuthorizationService().hasRoleReadByKeyResultId(id, authorizationUser);
Expand All @@ -45,7 +56,9 @@ public List<CheckIn> getAllCheckInsByKeyResult(Long keyResultId) {
AuthorizationUser authorizationUser = getAuthorizationService().getAuthorizationUser();
getAuthorizationService().hasRoleReadByKeyResultId(keyResultId, authorizationUser);
List<CheckIn> checkIns = getBusinessService().getAllCheckInsByKeyResult(keyResultId);
setRoleCreateOrUpdateCheckIn(checkIns, authorizationUser);
if (!checkIns.get(0).getKeyResult().getObjective().isArchived()) {
setRoleCreateOrUpdateCheckIn(checkIns, authorizationUser);
}
return checkIns;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ public Objective duplicateEntity(Long id, Objective objective) {
return getBusinessService().duplicateObjective(id, objective, authorizationUser);
}

@Override
public Objective getEntityById(Long id) {
AuthorizationUser authorizationUser = getAuthorizationService().getAuthorizationUser();
hasRoleReadById(id, authorizationUser);
Objective objective = getBusinessService().getEntityById(id);
if (!objective.isArchived()) {
objective.setWriteable(isWriteable(objective, authorizationUser));
}
return objective;
}

@Override
protected void hasRoleReadById(Long id, AuthorizationUser authorizationUser) {
getAuthorizationService().hasRoleReadByObjectiveId(id, authorizationUser);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static ch.puzzle.okr.service.authorization.AuthorizationService.hasRoleWriteAll;

Expand All @@ -28,7 +29,9 @@ public List<Overview> getFilteredOverview(Long quarterId, List<Long> teamIds, St
AuthorizationUser authorizationUser = authorizationService.getAuthorizationUser();
List<Overview> overviews = overviewBusinessService.getFilteredOverview(quarterId, teamIds, objectiveQuery,
authorizationUser);
setRoleCreateOrUpdateTeam(overviews, authorizationUser);
if (Objects.isNull(quarterId) || quarterId != 998) {
setRoleCreateOrUpdateTeam(overviews, authorizationUser);
}
return overviews;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public ObjectiveBusinessService(@Lazy KeyResultBusinessService keyResultBusiness
this.completedBusinessService = completedBusinessService;
}

public List<Objective> getAllObjectives() {
return objectivePersistenceService.findAll();
}

public Objective getEntityById(Long id) {
validator.validateOnGet(id);
return objectivePersistenceService.findById(id);
Expand All @@ -55,6 +59,7 @@ public Objective updateEntity(Long id, Objective objective, AuthorizationUser au
objective.setCreatedOn(savedObjective.getCreatedOn());
objective.setModifiedBy(authorizationUser.user());
objective.setModifiedOn(LocalDateTime.now());
objective.setArchived(false);
String not = " ";
if (isImUsed(objective, savedObjective)) {
objective.setQuarter(savedObjective.getQuarter());
Expand Down Expand Up @@ -87,6 +92,7 @@ private static boolean hasQuarterChanged(Objective objective, Objective savedObj
public Objective createEntity(Objective objective, AuthorizationUser authorizationUser) {
objective.setCreatedBy(authorizationUser.user());
objective.setCreatedOn(LocalDateTime.now());
objective.setArchived(false);
validator.validateOnCreate(objective);
return objectivePersistenceService.save(objective);
}
Expand Down Expand Up @@ -121,4 +127,10 @@ public void deleteEntityById(Long id) {
.forEach(keyResult -> keyResultBusinessService.deleteEntityById(keyResult.getId()));
objectivePersistenceService.deleteById(id);
}

public void archiveEntity(Long id) {
Objective savedObjective = objectivePersistenceService.findById(id);
savedObjective.setArchived(true);
objectivePersistenceService.save(savedObjective);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,14 @@ public List<Overview> getFilteredOverview(Long quarterId, List<Long> teamIds, St
return List.of();
}

List<Overview> overviews = overviewPersistenceService.getFilteredOverview(quarterId, teamIds, objectiveQuery,
authorizationUser);
List<Overview> overviews;
if (quarterId == 998) {
overviews = overviewPersistenceService.getArchiveOverview(teamIds, objectiveQuery, authorizationUser);
overviews.forEach(overview -> overview.setWriteable(false));
} else {
overviews = overviewPersistenceService.getFilteredOverview(quarterId, teamIds, objectiveQuery,
authorizationUser);
}
return sortOverview(overviews, authorizationUser);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package ch.puzzle.okr.service.business;

import ch.puzzle.okr.ErrorKey;
import ch.puzzle.okr.exception.OkrResponseStatusException;
import ch.puzzle.okr.models.Objective;
import ch.puzzle.okr.models.Quarter;
import ch.puzzle.okr.service.persistence.QuarterPersistenceService;
import ch.puzzle.okr.service.validation.QuarterValidationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

Expand All @@ -20,11 +18,13 @@ public class QuarterBusinessService {
private static final Logger logger = LoggerFactory.getLogger(QuarterBusinessService.class);

private final QuarterPersistenceService quarterPersistenceService;
private final ObjectiveBusinessService objectiveBusinessService;
private final QuarterValidationService validator;

public QuarterBusinessService(QuarterPersistenceService quarterPersistenceService,
QuarterValidationService validator) {
ObjectiveBusinessService objectiveBusinessService, QuarterValidationService validator) {
this.quarterPersistenceService = quarterPersistenceService;
this.objectiveBusinessService = objectiveBusinessService;
this.validator = validator;
}

Expand All @@ -36,7 +36,9 @@ public Quarter getQuarterById(Long quarterId) {
public List<Quarter> getQuarters() {
List<Quarter> mostCurrentQuarterList = quarterPersistenceService.getMostCurrentQuarters();
Quarter backlog = quarterPersistenceService.findByLabel("Backlog");
Quarter archive = quarterPersistenceService.findByLabel("Archiv");
mostCurrentQuarterList.add(0, backlog);
mostCurrentQuarterList.add(archive);
return mostCurrentQuarterList;
}

Expand Down Expand Up @@ -66,12 +68,27 @@ private void generateQuarter(YearMonth yearMonth) {
.build();
validator.validateOnGeneration(quarter);
quarterPersistenceService.save(quarter);
handleQuarterArchive();
}

public YearMonth getCurrentYearMonth() {
return YearMonth.now();
}

private void handleQuarterArchive() {
List<Quarter> mostCurrentQuarterList = quarterPersistenceService.getMostCurrentQuarters();
Quarter backlog = quarterPersistenceService.findByLabel("Backlog");
mostCurrentQuarterList.add(backlog);
List<Objective> allObjectives = objectiveBusinessService.getAllObjectives();

allObjectives.forEach(objective -> {
if (!mostCurrentQuarterList.contains(objective.getQuarter())) {
objectiveBusinessService.archiveEntity(objective.getId());
}
});
logger.info("Update archived Objectives");
}

@Scheduled(cron = "0 59 23 L * ?") // Cron expression for 23:59:00 on the last day of every month
public void scheduledGenerationQuarters() {
YearMonth yearMonth = getCurrentYearMonth();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class OverviewPersistenceService {

private static final Logger logger = LoggerFactory.getLogger(OverviewPersistenceService.class);
private static final String SELECT_OVERVIEW = "SELECT o FROM Overview o WHERE o.quarterId=:quarterId";
private static final String SELECT_ARCHIVE = "SELECT o FROM Overview o WHERE o.objectiveArchived=true";

private final EntityManager entityManager;
private final AuthorizationCriteria<Overview> authorizationCriteria;
Expand All @@ -35,4 +36,14 @@ public List<Overview> getFilteredOverview(Long quarterId, List<Long> teamIds, St
authorizationCriteria.setParameters(typedQuery, teamIds, objectiveQuery, authorizationUser);
return typedQuery.getResultList();
}

public List<Overview> getArchiveOverview(List<Long> teamIds, String objectiveQuery,
AuthorizationUser authorizationUser) {
String queryString = SELECT_ARCHIVE
+ authorizationCriteria.appendOverview(teamIds, objectiveQuery, authorizationUser);
logger.debug("select overview by teamIds={}: {}", teamIds, queryString);
TypedQuery<Overview> typedQuery = entityManager.createQuery(queryString, Overview.class);
authorizationCriteria.setParameters(typedQuery, teamIds, objectiveQuery, authorizationUser);
return typedQuery.getResultList();
}
}
Loading

0 comments on commit 7f3e626

Please sign in to comment.