public Map<User, Integer> getUnassignedWorkersMap(Project project) { Map<User, Integer> unassignedHasWork = new HashMap<User, Integer>(); Collection<BacklogItem> blis = getBlisInProjectAndItsIterations(project); Collection<User> assignees = backlogBusiness.getUsers(project, true); Set<User> workers = new HashSet<User>(); for (BacklogItem bli : blis) workers.addAll(bli.getResponsibles()); for (User worker : workers) unassignedHasWork.put(worker, assignees.contains(worker) ? 0 : 1); return unassignedHasWork; }
public void resetBliOrigEstAndEffortLeft(int backlogItemId) throws ObjectNotFoundException { BacklogItem backlogItem = backlogItemDAO.get(backlogItemId); if (backlogItem == null) { throw new ObjectNotFoundException("backlogItem.notFound"); } else { // Set effort left and original estimate to null backlogItem.setEffortLeft(null); backlogItem.setOriginalEstimate(null); backlogItemDAO.store(backlogItem); historyBusiness.updateBacklogHistory(backlogItem.getBacklog().getId()); } }
public void setTasksToDone(int backlogItemId) throws ObjectNotFoundException { BacklogItem backlogItem = backlogItemDAO.get(backlogItemId); if (backlogItem == null) { throw new ObjectNotFoundException("backlogItem.notFound"); } else { Map<Integer, State> doneStates = new HashMap<Integer, State>(); for (Task t : backlogItem.getTasks()) { doneStates.put(t.getId(), State.DONE); } taskBusiness.updateMultipleTasks(backlogItem, doneStates, new HashMap<Integer, String>()); } }
public void removeBacklogItem(int backlogItemId) throws ObjectNotFoundException { BacklogItem backlogItem = backlogItemDAO.get(backlogItemId); if (backlogItem == null) { throw new ObjectNotFoundException("Backlog item with given id was not found."); } // Remove all hourEntries related to this backlogItem hourEntryBusiness.removeHourEntriesByParent(backlogItem); // Store backlog to be able to update its history Backlog backlog = backlogItem.getBacklog(); backlog.getBacklogItems().remove(backlogItem); backlogItemDAO.remove(backlogItem); // Update backlog history for item's backlog historyBusiness.updateBacklogHistory(backlog.getId()); }
// TODO: write test public List<BacklogItem> getBacklogItemsByBacklog(Backlog backlog) { if (backlog != null) { List<BacklogItem> items = backlogItemDAO.getBacklogItemsByBacklog(backlog); Collections.sort(items, new BacklogItemComparator(new BacklogItemPriorityComparator())); // do we need to load spent effort sums if (settingBusiness.isHourReportingEnabled()) { Map<BacklogItem, AFTime> spentEffort = hourEntryBusiness.getSumsByBacklog(backlog); for (BacklogItem item : items) { if (spentEffort.containsKey(item)) { item.setEffortSpent(spentEffort.get(item)); } } } return items; } return null; }
public void moveItemToBacklog(BacklogItem item, Backlog backlog, boolean ignoreIterationGoal) { Backlog oldBacklog = item.getBacklog(); oldBacklog.getBacklogItems().remove(item); item.setBacklog(backlog); backlog.getBacklogItems().add(item); historyBusiness.updateBacklogHistory(oldBacklog.getId()); historyBusiness.updateBacklogHistory(backlog.getId()); if (item.getIterationGoal() != null && !ignoreIterationGoal) { item.getIterationGoal().getBacklogItems().remove(item); item.setIterationGoal(null); } if (!backlogBusiness.isUnderSameProduct(oldBacklog, backlog)) { // remove only product themes Collection<BusinessTheme> removeThese = new ArrayList<BusinessTheme>(); ; for (BusinessTheme theme : item.getBusinessThemes()) { if (!theme.isGlobal()) { removeThese.add(theme); } } for (BusinessTheme theme : removeThese) { item.getBusinessThemes().remove(theme); } } }
public List<BacklogItem> getBacklogItemsByBacklogWithCache(Backlog backlog) { List<BacklogItem> items = this.getBacklogItemsByBacklog(backlog); Map<BacklogItem, List<BacklogItemResponsibleContainer>> userData = this.getResponsiblesByBacklog(backlog); Map<BacklogItem, TodoMetrics> todoMetrics = this.getTasksByBacklog(backlog); Map<BacklogItem, List<BusinessTheme>> themes = this.businessThemeBusiness.getBacklogItemBusinessThemesByBacklog(backlog); for (BacklogItem item : items) { if (userData.get(item) != null) { item.setUserData(userData.get(item)); } if (todoMetrics.get(item) != null) { item.setTodoMetrics(todoMetrics.get(item)); } if (themes.get(item) != null) { item.setBusinessThemes(themes.get(item)); } } return items; }
public BacklogItem createBacklogItemFromTodo(int todoId) { BacklogItem backlogItem = new BacklogItem(); Task data = taskBusiness.getTask(todoId); if (data != null) { backlogItem.setName(data.getName()); backlogItem.setState(data.getState()); backlogItem.setBacklog(data.getBacklogItem().getBacklog()); backlogItem.setIterationGoal(data.getBacklogItem().getIterationGoal()); backlogItem.setPriority(data.getBacklogItem().getPriority()); backlogItem.setResponsibles(data.getBacklogItem().getResponsibles()); backlogItem.setBusinessThemes(data.getBacklogItem().getBusinessThemes()); } return backlogItem; }
public void setBacklogItemIterationGoal(BacklogItem item, IterationGoal iterationGoal) { if (iterationGoal != null && item.getBacklog() == iterationGoal.getIteration()) { if (item.getIterationGoal() != null) { item.getIterationGoal().getBacklogItems().remove(item); } item.setIterationGoal(iterationGoal); iterationGoal.getBacklogItems().add(item); } else { if (item.getIterationGoal() != null) { item.getIterationGoal().getBacklogItems().remove(item); } item.setIterationGoal(null); } }
/** {@inheritDoc} */ public List<User> getPossibleResponsibles(BacklogItem bli) { Set<User> userSet = new HashSet<User>(); // Get all enabled users userSet.addAll(userBusiness.getEnabledUsers()); // Get all previous responsibles if (bli != null) { userSet.addAll(bli.getResponsibles()); } // Create the list and sort it List<User> userList = new ArrayList<User>(userSet); Collections.sort(userList, new UserComparator()); return userList; }
public void updateBacklogItemStatePriorityAndEffortLeft( int backlogItemId, State newState, AFTime newEffortLeft, Priority newPriority) throws ObjectNotFoundException { BacklogItem backlogItem = backlogItemDAO.get(backlogItemId); if (backlogItem == null) { throw new ObjectNotFoundException("backlogItem.notFound"); } /* * Set the effort left as original estimate if backlog item's * original estimate is null in database */ if (backlogItem.getOriginalEstimate() == null) { backlogItem.setEffortLeft(newEffortLeft); backlogItem.setOriginalEstimate(newEffortLeft); } else if (backlogItem.getEffortLeft() != null && newEffortLeft == null) { backlogItem.setEffortLeft(new AFTime(0)); } else { backlogItem.setEffortLeft(newEffortLeft); } backlogItem.setState(newState); backlogItem.setPriority(newPriority); // set effortleft to 0 if state changed to done if (newState == State.DONE) backlogItem.setEffortLeft(new AFTime(0)); backlogItemDAO.store(backlogItem); historyBusiness.updateBacklogHistory(backlogItem.getBacklog().getId()); }
public BacklogItem storeBacklogItem( BacklogItem storable, Backlog backlog, BacklogItem dataItem, Set<User> responsibles, IterationGoal iterationGoal) { boolean historyUpdated = false; if (backlog == null) { throw new IllegalArgumentException("Backlog must not be null."); } if (dataItem == null) { throw new IllegalArgumentException("No data given."); } if (storable == null) { storable = new BacklogItem(); storable.setCreatedDate(Calendar.getInstance().getTime()); try { storable.setCreator(SecurityUtil.getLoggedUser()); // may fail if request is multithreaded } catch (Exception e) { } // however, saving item should not fail. } storable.setDescription(dataItem.getDescription()); storable.setEffortLeft(dataItem.getEffortLeft()); storable.setName(dataItem.getName()); if (storable.getOriginalEstimate() == null) { if (dataItem.getOriginalEstimate() == null) { storable.setOriginalEstimate(dataItem.getEffortLeft()); } else { storable.setOriginalEstimate(dataItem.getOriginalEstimate()); } } storable.setPriority(dataItem.getPriority()); storable.setState(dataItem.getState()); if (dataItem.getState() == State.DONE) { storable.setEffortLeft(new AFTime(0)); } else if (dataItem.getEffortLeft() == null) { storable.setEffortLeft(storable.getOriginalEstimate()); } Backlog originalBacklog = storable.getBacklog(); boolean isBeingMoved = false; if (storable.getBacklog() != null && storable.getBacklog() != backlog) { isBeingMoved = true; this.moveItemToBacklog(storable, backlog, false); historyUpdated = true; } else if (storable.getBacklog() == null) { storable.setBacklog(backlog); } storable.setResponsibles(responsibles); if (iterationGoal == null && isBeingMoved) { // Down stepping from Product/Project Story to Iteration Task boolean isTargetIteration = backlog instanceof fi.hut.soberit.agilefant.model.Iteration; boolean isSourceIteration = originalBacklog instanceof fi.hut.soberit.agilefant.model.Iteration; if (isTargetIteration && !isSourceIteration) { // Not using iterationGoalBusiness because of circular dependency in Spring. iterationGoal = new IterationGoal(); iterationGoal.setName(storable.getName()); iterationGoal.setIteration((Iteration) backlog); iterationGoalDAO.store(iterationGoal); } } this.setBacklogItemIterationGoal(storable, iterationGoal); BacklogItem persisted; if (storable.getId() == 0) { int persistedId = (Integer) backlogItemDAO.create(storable); persisted = backlogItemDAO.get(persistedId); } else { backlogItemDAO.store(storable); persisted = storable; } if (!historyUpdated) { historyBusiness.updateBacklogHistory(backlog.getId()); } return persisted; }
private void fillProjectPortfolioData(ProjectPortfolioData data) { HashMap<Project, String> userDataMap = new HashMap<Project, String>(); HashMap<Project, Integer> unassignedUserDataMap = new HashMap<Project, Integer>(); HashMap<Project, String> summaryLoadLeftMap = new HashMap<Project, String>(); HashMap<String, String> loadLeftData = new HashMap<String, String>(); HashMap<String, String> userOverheads = new HashMap<String, String>(); HashMap<String, String> totalUserOverheads = new HashMap<String, String>(); HashMap<String, Integer> unassignedUsersMap = new HashMap<String, Integer>(); Map<Project, List<User>> assignmentMap = new HashMap<Project, List<User>>(0); Map<Project, List<User>> nonAssignmentMap = new HashMap<Project, List<User>>(0); Set<String> keySet = new HashSet<String>(); Map<String, Integer> unassignedBlisMap = new HashMap<String, Integer>(); Collection<Project> projects = projectDAO.getOngoingProjects(); // Go trough all projects and bli:s for (Project pro : projects) { int assignedUsers = backlogBusiness.getNumberOfAssignedUsers(pro); int unestimatedBlis = 0; AFTime ongoingBliLoadLeft = new AFTime(0); Set<User> allUsers = new HashSet<User>(this.backlogBusiness.getUsers(pro, true)); HashSet<User> projectAssignments = new HashSet<User>(this.backlogBusiness.getUsers(pro, true)); List<User> nonAssignedUsers = new ArrayList<User>(); /* * ArrayList<User> assignments = new ArrayList<User>( * this.backlogBusiness.getUsers(pro, true)); */ Collection<BacklogItem> blis = getBlisInProjectAndItsIterations(pro); // Get overheads for users in this project for (Assignment ass : pro.getAssignments()) { if (ass.getDeltaOverhead() != null) { userOverheads.put( pro.getId() + "-" + ass.getUser().getId(), ass.getDeltaOverhead().toString()); AFTime total = new AFTime(0); if (pro.getDefaultOverhead() != null) { total.add(pro.getDefaultOverhead()); } total.add(ass.getDeltaOverhead()); totalUserOverheads.put(pro.getId() + "-" + ass.getUser().getId(), total.toString()); } else { if (pro.getDefaultOverhead() != null) { totalUserOverheads.put( pro.getId() + "-" + ass.getUser().getId(), pro.getDefaultOverhead().toString()); } else { totalUserOverheads.put(pro.getId() + "-" + ass.getUser().getId(), ""); } } } for (BacklogItem bli : blis) { if (bli.getResponsibles() != null) { ArrayList<User> responsibles = new ArrayList<User>(bli.getResponsibles()); if (bli.getEffortLeft() == null) { unestimatedBlis++; allUsers.addAll(bli.getResponsibles()); } else if (bli.getEffortLeft().getTime() != 0) { ongoingBliLoadLeft.add(bli.getEffortLeft()); allUsers.addAll(bli.getResponsibles()); } for (User resp : responsibles) { keySet.add(pro.getId() + "-" + resp.getId()); // Calculate and add effort from bli to user(s) assigned // Uses projectID-UserId as map key String effortForUsr = loadLeftData.get(pro.getId() + "-" + resp.getId()); if (effortForUsr != null) { AFTime usrLoadLeft = new AFTime(effortForUsr); if (bli.getEffortLeft() != null) { // Add effort to this user: (bli effort / number // of people assigned) AFTime newEffort = new AFTime(bli.getEffortLeft().getTime() / responsibles.size()); usrLoadLeft.add(newEffort); loadLeftData.put(pro.getId() + "-" + resp.getId(), usrLoadLeft.toString()); } } else { // no effort for user, create one if (bli.getEffortLeft() != null) { AFTime t = new AFTime(bli.getEffortLeft().getTime() / responsibles.size()); loadLeftData.put(pro.getId() + "-" + resp.getId(), t.toString()); } } // Check whether user is responsible for a bli in the // project but is currently not assigned to it if (!projectAssignments.contains(resp) && bli.getEffortLeft() == null) { unassignedUsersMap.put(pro.getId() + "-" + resp.getId(), 1); if (!nonAssignedUsers.contains(resp)) { nonAssignedUsers.add(resp); } } else if (!projectAssignments.contains(resp) && bli.getEffortLeft().getTime() != 0) { unassignedUsersMap.put(pro.getId() + "-" + resp.getId(), 1); if (!nonAssignedUsers.contains(resp)) { nonAssignedUsers.add(resp); } } if (bli.getEffortLeft() == null) { int numberOfUnestimatedBlis = 1; if (unassignedBlisMap.get(pro.getId() + "-" + resp.getId()) != null) { numberOfUnestimatedBlis = unassignedBlisMap.get(pro.getId() + "-" + resp.getId()) + 1; } unassignedBlisMap.put(pro.getId() + "-" + resp.getId(), numberOfUnestimatedBlis); } } } } int unassignedUsers = allUsers.size() - assignedUsers; String userDataString = "" + assignedUsers; EffortSumData loadData = new EffortSumData(); loadData.setEffortHours(ongoingBliLoadLeft); loadData.setNonEstimatedItems(unestimatedBlis); String loadLeftString = loadData.toString(); summaryLoadLeftMap.put(pro, loadLeftString); userDataMap.put(pro, userDataString); unassignedUserDataMap.put(pro, unassignedUsers); assignmentMap.put(pro, new ArrayList<User>(this.backlogBusiness.getUsers(pro, true))); nonAssignmentMap.put(pro, nonAssignedUsers); } for (String key : keySet) { String value = loadLeftData.get(key); // Fetch aftime-value and non-estimated items to a // EffortSumData-object to get correct output string. AFTime aftimeValue = new AFTime(0); if (value != null) aftimeValue = new AFTime(value); int userUnestimatedBlis = 0; if (unassignedBlisMap.get(key) != null) userUnestimatedBlis += unassignedBlisMap.get(key); EffortSumData sumData = new EffortSumData(); sumData.setEffortHours(aftimeValue); sumData.setNonEstimatedItems(userUnestimatedBlis); value = sumData.toString(); loadLeftData.put(key, value); } data.setUnassignedUsers(unassignedUsersMap); data.setAssignedUsers(assignmentMap); data.setSummaryUserData(userDataMap); data.setSummaryUnassignedUserData(unassignedUserDataMap); data.setSummaryLoadLeftData(summaryLoadLeftMap); data.setLoadLefts(loadLeftData); data.setUserOverheads(userOverheads); data.setTotalUserOverheads(totalUserOverheads); data.setNonAssignedUsers(nonAssignmentMap); }