package com.qprogramming.tasq.agile; import com.qprogramming.tasq.support.PeriodHelper; import com.qprogramming.tasq.support.Utils; import com.qprogramming.tasq.task.DisplayTask; import com.qprogramming.tasq.task.Task; import com.qprogramming.tasq.task.TaskService; import com.qprogramming.tasq.task.TaskState; import com.qprogramming.tasq.task.worklog.WorkLog; import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.Period; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import static com.qprogramming.tasq.agile.AgileData.ALL; import static com.qprogramming.tasq.agile.AgileData.CLOSED; @Service public class AgileService { private SprintRepository sprintRepo; private ReleaseRepository releaseRepo; private TaskService taskSrv; @Autowired public AgileService(SprintRepository sprintRepo, ReleaseRepository releaseRepo, TaskService taskSrv) { this.sprintRepo = sprintRepo; this.releaseRepo = releaseRepo; this.taskSrv = taskSrv; } public Sprint findByProjectIdAndActiveTrue(Long id) { return sprintRepo.findByProjectIdAndActiveTrue(id); } public List<Sprint> findByProjectIdAndFinished(String id, boolean finished) { return sprintRepo.findByProjectProjectIdAndFinished(id, finished); } public List<Sprint> findByProjectId(Long id) { return sprintRepo.findByProjectId(id); } public Sprint findById(Long sprintID) { return sprintRepo.findById(sprintID); } public Sprint save(Sprint sprint) { return sprintRepo.save(sprint); } public void delete(Sprint sprint) { sprintRepo.delete(sprint); } public Sprint findByProjectIdAndSprintNo(Long id, Long sprintNo) { return sprintRepo.findByProjectIdAndSprintNo(id, sprintNo); } public List<DisplaySprint> convertToDisplay(List<Sprint> projectSprints) { return projectSprints.stream().map(DisplaySprint::new).collect(Collectors.toCollection(LinkedList::new)); } public Map<String, Float> fillTimeBurndownMap(List<WorkLog> wrkList, DateTime startTime, DateTime endTime) { int sprintDays = Days.daysBetween(startTime, endTime).getDays() + 1; Map<LocalDate, Period> timeBurndownMap = fillTimeMap(wrkList); Map<String, Float> resultsBurned = new LinkedHashMap<String, Float>(); for (int i = 0; i < sprintDays; i++) { LocalDate date = new LocalDate(startTime.plusDays(i)); Period value = timeBurndownMap.get(new LocalDate(date)); if (date.isAfter(LocalDate.now())) { resultsBurned.put(date.toString(), 0f); } else { if (value != null) { Float result = Utils.getFloatValue(value); resultsBurned.put(date.toString(), result); } else { resultsBurned.put(date.toString(), 0f); } } } return resultsBurned; } /** * Fills time map with worklogs in format <Date, Period Burned> Only events * with before present day are added * * @param worklogList * @return **/ private Map<LocalDate, Period> fillTimeMap(List<WorkLog> worklogList) { Map<LocalDate, Period> burndownMap = new LinkedHashMap<LocalDate, Period>(); for (WorkLog workLog : worklogList) { if (workLog.getActivity() != null) { LocalDate dateLogged = new LocalDate(workLog.getRawTime()); Period value = burndownMap.get(dateLogged); if (value == null) { value = workLog.getActivity(); } else { value = PeriodHelper.plusPeriods(value, workLog.getActivity()); } burndownMap.put(dateLogged, value); } } return burndownMap; } public Release findByProjectIdAndRelease(Long id, String releaseNo) { return releaseRepo.findByProjectIdAndRelease(id, releaseNo); } public List<Release> findReleaseByProjectIdOrderByDateDesc(Long id) { return releaseRepo.findByProjectIdOrderByEndDateDesc(id); } public Release save(Release release) { return releaseRepo.save(release); } /** * Fetches last release from project * * @param id * @return */ public Release findLastReleaseByProjectId(Long id) { List<Release> list = findReleaseByProjectIdOrderByDateDesc(id); if (list.isEmpty()) { return null; } return list.get(list.size() - 1); } public boolean taskInActiveSprint(Task task) { if (!task.isInSprint()) { return false; } else { for (Sprint sprint : task.getSprints()) { if (sprint.isActive()) { return true; } } return false; } } /** * Set tasks based if task was finished in endTime or not. If was finished before * , it will be moved to CLOSED tasks, otherwise it will be in ALL * * @param endTime - end time before tasks should be finished * @param tasks - task liest */ public void setTasksByStatus(AgileData data, DateTime endTime, List<Task> tasks) { for (Task task : tasks) { DateTime finishDate = null; if (task.getRawFinishDate() != null) { finishDate = new DateTime(task.getRawFinishDate()); } taskSrv.addSubtaskTimers(task); if (task.getState().equals(TaskState.CLOSED) && (finishDate != null && endTime.isAfter(finishDate))) { data.getTasks().get(CLOSED) .add(new DisplayTask(task)); } else { data.getTasks().get(ALL) .add(new DisplayTask(task)); } } } }