3204 Set reviewer targets by calendar year
This commit is contained in:
parent
f2cfb07a29
commit
0d1650f3f3
core/src/main
java/se/su/dsv/scipro/reviewing
ReviewerCapacityService.javaReviewerCapacityServiceImpl.javaReviewerTarget.javaReviewerTargetRepository.javaReviewerTargetRepositoryImpl.java
resources/db/migration
@ -3,11 +3,19 @@ package se.su.dsv.scipro.reviewing;
|
||||
import se.su.dsv.scipro.system.Unit;
|
||||
import se.su.dsv.scipro.system.User;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Year;
|
||||
import java.util.List;
|
||||
|
||||
public interface ReviewerCapacityService {
|
||||
void assignTarget(User reviewer, DateRange dateRange, int target);
|
||||
record Target(int spring, int autumn, String note) {}
|
||||
|
||||
default void assignTarget(User reviewer, DateRange dateRange, int target) {
|
||||
Year year = Year.from(dateRange.from());
|
||||
int spring = dateRange.from().getMonthValue() < 7 ? target : 0;
|
||||
int autumn = dateRange.from().getMonthValue() > 6 ? target : 0;
|
||||
assignTarget(reviewer, year, new Target(spring, autumn, ""));
|
||||
}
|
||||
void assignTarget(User reviewer, Year year, Target target);
|
||||
|
||||
List<Unit> getUnitsWithReviewers();
|
||||
|
||||
@ -15,7 +23,12 @@ public interface ReviewerCapacityService {
|
||||
|
||||
List<User> getActiveReviewersOnUnit(Unit unit);
|
||||
|
||||
int getTarget(User reviewerObject, DateRange dateRange);
|
||||
default int getTarget(User reviewerObject, DateRange dateRange) {
|
||||
Year year = Year.from(dateRange.from());
|
||||
return getTarget(reviewerObject, year).spring();
|
||||
}
|
||||
|
||||
Target getTarget(User reviewer, Year year);
|
||||
|
||||
String getNote(User reviewer, DateRange dateRange);
|
||||
|
||||
|
@ -12,6 +12,8 @@ import se.su.dsv.scipro.system.UserService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
import java.time.Year;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@ -41,20 +43,23 @@ class ReviewerCapacityServiceImpl implements ReviewerCapacityService, ReviewerAs
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignTarget(User reviewer, DateRange dateRange, int target) {
|
||||
Optional<ReviewerTarget> currentTarget = reviewerTargetRepository.getExactReviewTarget(reviewer, dateRange);
|
||||
if (currentTarget.isPresent()) {
|
||||
ReviewerTarget targetToUpdate = currentTarget.get();
|
||||
targetToUpdate.setTarget(target);
|
||||
public void assignTarget(User reviewer, Year year, Target target) {
|
||||
Optional<ReviewerTarget> reviewerTarget = reviewerTargetRepository.getReviewerTarget(reviewer, year);
|
||||
if (reviewerTarget.isPresent()) {
|
||||
ReviewerTarget targetToUpdate = reviewerTarget.get();
|
||||
targetToUpdate.setSpring(target.spring());
|
||||
targetToUpdate.setAutumn(target.autumn());
|
||||
targetToUpdate.setNote(target.note());
|
||||
reviewerTargetRepository.save(targetToUpdate);
|
||||
}
|
||||
else {
|
||||
ReviewerTarget reviewerTarget = new ReviewerTarget();
|
||||
reviewerTarget.setReviewer(reviewer);
|
||||
reviewerTarget.setFromDate(dateRange.from());
|
||||
reviewerTarget.setToDate(dateRange.to());
|
||||
reviewerTarget.setTarget(target);
|
||||
reviewerTargetRepository.save(reviewerTarget);
|
||||
ReviewerTarget reviewerTargetToSave = new ReviewerTarget();
|
||||
reviewerTargetToSave.setReviewer(reviewer);
|
||||
reviewerTargetToSave.setYear(year.getValue());
|
||||
reviewerTargetToSave.setSpring(target.spring());
|
||||
reviewerTargetToSave.setAutumn(target.autumn());
|
||||
reviewerTargetToSave.setNote(target.note());
|
||||
reviewerTargetRepository.save(reviewerTargetToSave);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,15 +87,15 @@ class ReviewerCapacityServiceImpl implements ReviewerCapacityService, ReviewerAs
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTarget(User reviewerObject, DateRange dateRange) {
|
||||
return getTarget(reviewerObject, dateRange.from())
|
||||
.map(ReviewerTarget::getTarget)
|
||||
.orElse(0);
|
||||
public Target getTarget(User reviewer, Year year) {
|
||||
return reviewerTargetRepository.getReviewerTarget(reviewer, year)
|
||||
.map(reviewerTarget -> new Target(reviewerTarget.getSpring(), reviewerTarget.getAutumn(), reviewerTarget.getNote()))
|
||||
.orElse(new Target(0, 0, ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNote(User reviewer, DateRange dateRange) {
|
||||
return reviewerTargetRepository.getExactReviewTarget(reviewer, dateRange)
|
||||
return reviewerTargetRepository.getReviewerTarget(reviewer, Year.from(dateRange.from()))
|
||||
.map(ReviewerTarget::getNote)
|
||||
.orElse("");
|
||||
}
|
||||
@ -98,7 +103,7 @@ class ReviewerCapacityServiceImpl implements ReviewerCapacityService, ReviewerAs
|
||||
@Override
|
||||
@Transactional
|
||||
public void setNote(User reviewer, DateRange dateRange, String note) {
|
||||
Optional<ReviewerTarget> currentTarget = reviewerTargetRepository.getExactReviewTarget(reviewer, dateRange);
|
||||
Optional<ReviewerTarget> currentTarget = reviewerTargetRepository.getReviewerTarget(reviewer, Year.from(dateRange.from()));
|
||||
if (currentTarget.isPresent()) {
|
||||
ReviewerTarget targetToUpdate = currentTarget.get();
|
||||
targetToUpdate.setNote(note);
|
||||
@ -107,17 +112,14 @@ class ReviewerCapacityServiceImpl implements ReviewerCapacityService, ReviewerAs
|
||||
else {
|
||||
ReviewerTarget reviewerTarget = new ReviewerTarget();
|
||||
reviewerTarget.setReviewer(reviewer);
|
||||
reviewerTarget.setFromDate(dateRange.from());
|
||||
reviewerTarget.setToDate(dateRange.to());
|
||||
reviewerTarget.setYear(dateRange.from().getYear());
|
||||
reviewerTarget.setNote(note);
|
||||
reviewerTargetRepository.save(reviewerTarget);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<ReviewerTarget> getTarget(User reviewer, LocalDate date) {
|
||||
return reviewerTargetRepository.getReviewerTargets(reviewer, date)
|
||||
.stream()
|
||||
.max(Comparator.comparing(ReviewerTarget::getTarget));
|
||||
return reviewerTargetRepository.getReviewerTarget(reviewer, Year.from(date));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -130,8 +132,8 @@ class ReviewerCapacityServiceImpl implements ReviewerCapacityService, ReviewerAs
|
||||
List<ReviewerCandidates.Candidate> unavailable = new ArrayList<>();
|
||||
for (User reviewer : reviewers) {
|
||||
Optional<ReviewerTarget> reviewerPeriodTarget = getTarget(reviewer, date);
|
||||
int target = reviewerPeriodTarget.map(ReviewerTarget::getTarget).orElse(0);
|
||||
int assigned = reviewerPeriodTarget.map(this::countAssignedReviews).orElse(0);
|
||||
int target = reviewerPeriodTarget.map(rt -> getPeriodTarget(rt, date)).orElse(0);
|
||||
int assigned = countAssignedReviews(reviewer, date);
|
||||
String note = reviewerPeriodTarget.map(ReviewerTarget::getNote).orElse("");
|
||||
ReviewerCandidates.Candidate candidate = new ReviewerCandidates.Candidate(reviewer, target, assigned, note);
|
||||
|
||||
@ -158,6 +160,10 @@ class ReviewerCapacityServiceImpl implements ReviewerCapacityService, ReviewerAs
|
||||
return new ReviewerCandidates(good, mismatched, busy, unavailable);
|
||||
}
|
||||
|
||||
private int getPeriodTarget(ReviewerTarget reviewerTarget, LocalDate date) {
|
||||
return date.getMonthValue() <= Month.JUNE.getValue() ? reviewerTarget.getSpring() : reviewerTarget.getAutumn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReviewerAssignment assignReviewer(Project project, User reviewer) {
|
||||
if (project.getHeadSupervisor().equals(reviewer)) {
|
||||
@ -175,11 +181,12 @@ class ReviewerCapacityServiceImpl implements ReviewerCapacityService, ReviewerAs
|
||||
}
|
||||
}
|
||||
|
||||
private int countAssignedReviews(ReviewerTarget reviewerTarget) {
|
||||
return countAssignedReviews(reviewerTarget.getReviewer(), reviewerTarget.getFromDate(), reviewerTarget.getToDate());
|
||||
}
|
||||
|
||||
private int countAssignedReviews(User reviewer, LocalDate fromDate, LocalDate toDate) {
|
||||
return decisionRepository.countDecisions(reviewer, fromDate, toDate);
|
||||
private int countAssignedReviews(User reviewer, LocalDate fromDate) {
|
||||
if (fromDate.getMonthValue() <= Month.JUNE.getValue()) {
|
||||
return decisionRepository.countDecisions(reviewer, LocalDate.of(fromDate.getYear(), Month.JANUARY, 1), LocalDate.of(fromDate.getYear(), Month.JUNE, 30));
|
||||
}
|
||||
else {
|
||||
return decisionRepository.countDecisions(reviewer, LocalDate.of(fromDate.getYear(), Month.JULY, 1), LocalDate.of(fromDate.getYear(), Month.DECEMBER, 31));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ public class ReviewerTarget extends DomainObject {
|
||||
@JoinColumn(name = "reviewer_id", nullable = false)
|
||||
private User reviewer;
|
||||
|
||||
@Column(name = "target", nullable = false)
|
||||
private int target;
|
||||
@Column(name = "year", nullable = false)
|
||||
private int year;
|
||||
|
||||
@Column(name = "from_date", nullable = false)
|
||||
private java.time.LocalDate fromDate;
|
||||
@Column(name = "spring", nullable = false)
|
||||
private int spring;
|
||||
|
||||
@Column(name = "to_date", nullable = false)
|
||||
private java.time.LocalDate toDate;
|
||||
@Column(name = "autumn", nullable = false)
|
||||
private int autumn;
|
||||
|
||||
@Column(name = "note")
|
||||
private String note;
|
||||
@ -53,28 +53,28 @@ public class ReviewerTarget extends DomainObject {
|
||||
this.reviewer = reviewer;
|
||||
}
|
||||
|
||||
public int getTarget() {
|
||||
return target;
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setTarget(int target) {
|
||||
this.target = target;
|
||||
public void setYear(int year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public LocalDate getFromDate() {
|
||||
return fromDate;
|
||||
public int getSpring() {
|
||||
return spring;
|
||||
}
|
||||
|
||||
public void setFromDate(LocalDate fromDate) {
|
||||
this.fromDate = fromDate;
|
||||
public void setSpring(int spring) {
|
||||
this.spring = spring;
|
||||
}
|
||||
|
||||
public LocalDate getToDate() {
|
||||
return toDate;
|
||||
public int getAutumn() {
|
||||
return autumn;
|
||||
}
|
||||
|
||||
public void setToDate(LocalDate toDate) {
|
||||
this.toDate = toDate;
|
||||
public void setAutumn(int autumn) {
|
||||
this.autumn = autumn;
|
||||
}
|
||||
|
||||
public String getNote() {
|
||||
@ -87,22 +87,29 @@ public class ReviewerTarget extends DomainObject {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReviewerTarget{" + "id=" + id + ", reviewer=" + reviewer + ", target=" + target + ", fromDate=" + fromDate + ", toDate=" + toDate + ", note=" + note + '}';
|
||||
return "ReviewerTarget{" +
|
||||
"id=" + id +
|
||||
", reviewer=" + reviewer +
|
||||
", year=" + year +
|
||||
", spring=" + spring +
|
||||
", autumn=" + autumn +
|
||||
", note='" + note + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof ReviewerTarget that
|
||||
&& target == that.target
|
||||
&& year == that.year
|
||||
&& spring == that.spring
|
||||
&& autumn == that.autumn
|
||||
&& Objects.equals(id, that.id)
|
||||
&& Objects.equals(reviewer, that.reviewer)
|
||||
&& Objects.equals(fromDate, that.fromDate)
|
||||
&& Objects.equals(toDate, that.toDate)
|
||||
&& Objects.equals(note, that.note);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), id, reviewer, target, fromDate, toDate, note);
|
||||
return Objects.hash(super.hashCode(), id, reviewer, year, spring, autumn, note);
|
||||
}
|
||||
}
|
||||
|
@ -2,14 +2,11 @@ package se.su.dsv.scipro.reviewing;
|
||||
|
||||
import se.su.dsv.scipro.system.User;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.time.Year;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface ReviewerTargetRepository {
|
||||
void save(ReviewerTarget reviewerTarget);
|
||||
|
||||
List<ReviewerTarget> getReviewerTargets(User reviewer, LocalDate date);
|
||||
|
||||
Optional<ReviewerTarget> getExactReviewTarget(User reviewer, DateRange dateRange);
|
||||
Optional<ReviewerTarget> getReviewerTarget(User reviewer, Year year);
|
||||
}
|
||||
|
@ -7,8 +7,7 @@ import se.su.dsv.scipro.system.User;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.time.Year;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ReviewerTargetRepositoryImpl extends AbstractRepository implements ReviewerTargetRepository {
|
||||
@ -29,22 +28,12 @@ public class ReviewerTargetRepositoryImpl extends AbstractRepository implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReviewerTarget> getReviewerTargets(User reviewer, LocalDate date) {
|
||||
return from(QReviewerTarget.reviewerTarget)
|
||||
.where(QReviewerTarget.reviewerTarget.reviewer.eq(reviewer)
|
||||
.and(QReviewerTarget.reviewerTarget.fromDate.loe(date))
|
||||
.and(QReviewerTarget.reviewerTarget.toDate.goe(date)))
|
||||
.fetch();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<ReviewerTarget> getExactReviewTarget(User reviewer, DateRange dateRange) {
|
||||
public Optional<ReviewerTarget> getReviewerTarget(User reviewer, Year year) {
|
||||
ReviewerTarget current =
|
||||
from(QReviewerTarget.reviewerTarget)
|
||||
.where(QReviewerTarget.reviewerTarget.reviewer.eq(reviewer)
|
||||
.and(QReviewerTarget.reviewerTarget.fromDate.eq(dateRange.from()))
|
||||
.and(QReviewerTarget.reviewerTarget.toDate.eq(dateRange.to())))
|
||||
.fetchOne();
|
||||
.where(QReviewerTarget.reviewerTarget.reviewer.eq(reviewer))
|
||||
.where(QReviewerTarget.reviewerTarget.year.eq(year.getValue()))
|
||||
.fetchOne();
|
||||
return Optional.ofNullable(current);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
CREATE TABLE `reviewer_target_migration`
|
||||
(
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`dateCreated` DATETIME NOT NULL,
|
||||
`lastModified` DATETIME NOT NULL,
|
||||
`version` INT NOT NULL,
|
||||
`reviewer_id` BIGINT NOT NULL,
|
||||
`year` INT NOT NULL,
|
||||
`spring` INT NOT NULL,
|
||||
`autumn` INT NOT NULL,
|
||||
`note` TEXT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `UK_ReviewerTarget_ReviewerId_Year` (`reviewer_id`, `year`),
|
||||
CONSTRAINT `FK_ReviewerTarget_ReviewerId` FOREIGN KEY (`reviewer_id`) REFERENCES `user` (`id`)
|
||||
);
|
||||
|
||||
INSERT INTO `reviewer_target_migration`
|
||||
(`dateCreated`, `lastModified`, `version`, `reviewer_id`, `year`, `spring`, `autumn`, `note`)
|
||||
SELECT MIN(`dateCreated`), MAX(`lastModified`), MAX(`version`), `reviewer_id`, YEAR(`from_date`), 0, 0, NULL
|
||||
FROM `reviewer_target`
|
||||
GROUP BY `reviewer_id`, YEAR(`from_date`);
|
||||
|
||||
UPDATE `reviewer_target_migration`
|
||||
SET `spring` = COALESCE((SELECT SUM(`target`) FROM `reviewer_target` WHERE `reviewer_target`.`reviewer_id` = `reviewer_target_migration`.`reviewer_id` AND `reviewer_target`.`from_date` >= CONCAT(`year`, '-01-01') AND `reviewer_target`.`from_date` < CONCAT(`year`, '-07-01')), 0),
|
||||
`autumn` = COALESCE((SELECT SUM(`target`) FROM `reviewer_target` WHERE `reviewer_target`.`reviewer_id` = `reviewer_target_migration`.`reviewer_id` AND `reviewer_target`.`from_date` >= CONCAT(`year`, '-07-01') AND `reviewer_target`.`from_date` < CONCAT(`year` + 1, '-01-01')), 0);
|
||||
|
||||
UPDATE `reviewer_target_migration`
|
||||
SET note = (SELECT GROUP_CONCAT(`note`) FROM `reviewer_target` WHERE `reviewer_target`.`reviewer_id` = `reviewer_target_migration`.`reviewer_id` AND YEAR(`from_date`) = `year` AND `note` IS NOT NULL)
|
||||
WHERE `note` IS NULL;
|
||||
|
||||
DROP TABLE `reviewer_target`;
|
||||
RENAME TABLE `reviewer_target_migration` TO `reviewer_target`;
|
Loading…
x
Reference in New Issue
Block a user