/** {@inheritDoc} */
 public Map<BusinessTheme, AFTime> formatThemeBindings(Project proj) {
   Map<BusinessTheme, Collection<BacklogThemeBinding>> tmp =
       new HashMap<BusinessTheme, Collection<BacklogThemeBinding>>();
   if (proj.getIterations().size() > 0) {
     List<BacklogThemeBinding> bindings = projectDAO.getProjectThemeData(proj);
     // iteration themes
     for (BacklogThemeBinding bind : bindings) {
       if (tmp.get(bind.getBusinessTheme()) == null) {
         tmp.put(bind.getBusinessTheme(), new ArrayList<BacklogThemeBinding>());
       }
       tmp.get(bind.getBusinessTheme()).add(bind);
     }
   }
   // project themes
   if (proj.getBusinessThemeBindings() != null) {
     for (BacklogThemeBinding bind : proj.getBusinessThemeBindings()) {
       if (tmp.get(bind.getBusinessTheme()) == null) {
         tmp.put(bind.getBusinessTheme(), new ArrayList<BacklogThemeBinding>());
       }
       tmp.get(bind.getBusinessTheme()).add(bind);
     }
   }
   Map<BusinessTheme, AFTime> ret = new HashMap<BusinessTheme, AFTime>();
   // format
   for (BusinessTheme theme : tmp.keySet()) {
     AFTime sum = new AFTime(0);
     for (BacklogThemeBinding bin : tmp.get(theme)) {
       sum.add(bin.getBoundEffort());
     }
     ret.put(theme, sum);
   }
   return ret;
 }
  /**
   * Calculates overheads for user from given backlogs( projects)
   *
   * @param from
   * @param weeksAhead
   * @param items
   * @return
   */
  public HashMap<Integer, String> calculateOverheads(
      Date from, int weeksAhead, List<Backlog> items, User user) {
    GregorianCalendar cal = new GregorianCalendar();
    CalendarUtils cUtils = new CalendarUtils();
    HashMap<Integer, String> overheads = new HashMap<Integer, String>();

    Date start = from;
    Date end = cUtils.nextMonday(start);
    cal.setTime(start);
    Integer week = cal.get(GregorianCalendar.WEEK_OF_YEAR);
    List<Assignment> assignments = new ArrayList<Assignment>(user.getAssignments());

    for (int i = 1; i <= weeksAhead; i++) {
      // 1. Get Backlogs that hit for the week
      log.debug("Projects searched from :" + start);
      log.debug("Projects searched ending :" + end);
      cal.setTime(start);
      week = cal.get(GregorianCalendar.WEEK_OF_YEAR);
      log.debug("Calculating overhead for week" + week);

      // 2. Get projects that hit current week
      List<Backlog> list = this.getProjectsAndIterationsInTimeFrame(items, start, end);
      log.debug(list.size() + " projects found for given time frame");

      // 3. Calculate overhead sum from items in those projects
      AFTime overhead = new AFTime(0);
      for (Backlog blog : list) {
        // Only check assignments for Projects (overhead
        // only set for projects not iterations)
        if (blog.getClass().equals(Project.class)) {
          Project pro = (Project) blog;
          for (Assignment ass : assignments) {
            if (ass.getBacklog().equals((Backlog) pro)) {
              if (pro.getDefaultOverhead() != null) {
                overhead.add(pro.getDefaultOverhead());
                log.debug("Added overhead from project: " + pro.getDefaultOverhead());
              }
              if (ass.getDeltaOverhead() != null) {
                overhead.add(ass.getDeltaOverhead());
                log.debug("Added overhead from user: "******"Class was iteration class, overhead :" + blog.getClass());
        }
      }
      overheads.put(week, overhead.toString());
      start = cUtils.nextMonday(start);
      end = cUtils.nextMonday(start);
      cal.setTime(start);
      week = cal.get(GregorianCalendar.WEEK_OF_YEAR);
    }

    return overheads;
  }
 public Map<Integer, AFTime> calculateTotalOverheads(Project project) {
   Map<Integer, AFTime> totalOverheads = new HashMap<Integer, AFTime>();
   if (project != null) {
     for (Assignment ass : project.getAssignments()) {
       AFTime totalOverhead = new AFTime(0);
       if (project.getDefaultOverhead() != null) {
         totalOverhead.add(project.getDefaultOverhead());
       }
       if (ass.getDeltaOverhead() != null) {
         totalOverhead.add(ass.getDeltaOverhead());
       }
       totalOverheads.put(ass.getUser().getId(), totalOverhead);
     }
   }
   return totalOverheads;
 }
 /**
  * Calculate whether given hours can be fitted to the given week. Each day is assumed 8 hours
  * long.
  *
  * @param currentWeek
  * @param targetWeek
  * @param totalWorkload
  * @return
  */
 private boolean isAccommodableWorkload(
     int currentWeek, int targetWeek, AFTime totalWorkload, User user) {
   if (user == null) {
     return false;
   }
   long totalInWeek = 5;
   int daysLeft = 5;
   if (currentWeek == targetWeek) {
     Calendar cal = GregorianCalendar.getInstance();
     daysLeft = 1;
     while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.FRIDAY && daysLeft < 6) {
       cal.add(Calendar.DAY_OF_YEAR, 1);
       daysLeft++;
     }
   }
   totalInWeek =
       (long)
           (user.getWeekHours().getTime()
               * (1.0 * daysLeft * settingBusiness.getCriticalLow() / (5 * 100)));
   if (totalInWeek < totalWorkload.getTime()) {
     return false;
   }
   return true;
 }
  public HashMap<Integer, String> calculateEffortLefts(
      Date from, int weeksAhead, Map<Backlog, List<BacklogItem>> items) {
    GregorianCalendar cal = new GregorianCalendar();
    CalendarUtils cUtils = new CalendarUtils();
    HashMap<Integer, String> effortLefts = new HashMap<Integer, String>();

    Date start = from;
    Date end = cUtils.nextMonday(start);
    cal.setTime(start);
    Integer week = cal.get(GregorianCalendar.WEEK_OF_YEAR);
    for (int i = 1; i <= weeksAhead; i++) {
      // 1. Get Backlogs that hit for the week
      log.debug("Projects searched from :" + start);
      log.debug("Projects searched ending :" + end);
      cal.setTime(start);
      week = cal.get(GregorianCalendar.WEEK_OF_YEAR);
      log.debug("Calculating sums for week" + week);

      // 2. Get projects that hit current week
      List<Backlog> list =
          this.getProjectsAndIterationsInTimeFrame(
              new ArrayList<Backlog>(items.keySet()), start, end);
      log.debug(list.size() + " projects found for given time frame");

      // 3. Calculate effort sum from items in those projects
      AFTime total = new AFTime(0);
      for (Backlog blog : list) {
        Project pro = null;
        Iteration it = null;
        if (blog.getClass().equals(Project.class)) {
          pro = (Project) blog;
          List<BacklogItem> blis = items.get((Backlog) pro);
          if (blis != null) {
            // Dividing for weeks that project hits
            AFTime sum =
                this.backlogBusiness.getEffortLeftResponsibleDividedSum(blis).getEffortHours();
            int projectLength = CalendarUtils.getLengthInDays(pro.getStartDate(), pro.getEndDate());
            log.debug("Week Project length: " + projectLength + " days");
            int weekEndDaysInProject = cUtils.getWeekEndDays(pro.getStartDate(), pro.getEndDate());
            log.debug("Excluding " + weekEndDaysInProject + " days from project as week end days");
            projectLength = projectLength - weekEndDaysInProject;
            if (projectLength == 0) { // TODO Find better way to
              // prevent null divination
              // if project on weekend
              projectLength = 1;
            }
            List<Date> dates =
                cUtils.getProjectDaysList(
                    pro.getStartDate(),
                    pro.getEndDate(),
                    start,
                    new Date(end.getTime() - 86400000L),
                    false);
            int projectDaysOnWeek = 0;
            if (dates != null) {
              projectDaysOnWeek = dates.size();
            }
            log.debug("Week Project length (modified): " + projectLength + " days");
            log.debug("Week Project days:" + projectDaysOnWeek);
            log.debug(
                "Week Project effort per day: " + new AFTime(sum.getTime() / (long) projectLength));
            sum = new AFTime((sum.getTime() / (long) projectLength) * projectDaysOnWeek);
            if (sum != null) {
              total.add(sum);
              log.debug("Week effort sum: " + sum);
            }
          }
        }
        if (blog.getClass().equals(Iteration.class)) {
          it = (Iteration) blog;
          List<BacklogItem> blis = items.get((Backlog) it);
          if (blis != null) {
            // Dividing for weeks that project hits
            AFTime sum =
                this.backlogBusiness.getEffortLeftResponsibleDividedSum(blis).getEffortHours();
            int projectLength = CalendarUtils.getLengthInDays(it.getStartDate(), it.getEndDate());
            log.debug("Week Project length: " + projectLength + " days");
            int weekEndDaysInProject = cUtils.getWeekEndDays(it.getStartDate(), it.getEndDate());
            log.debug("Excluding " + weekEndDaysInProject + " days from project as week end days");
            projectLength = projectLength - weekEndDaysInProject;
            if (projectLength == 0) { // TODO Find better way to
              // prevent null division if
              // project on weekend
              projectLength = 1;
            }
            List<Date> dates =
                cUtils.getProjectDaysList(
                    it.getStartDate(),
                    it.getEndDate(),
                    start,
                    new Date(end.getTime() - 86400000L),
                    false);
            int projectDaysOnWeek = 0;
            if (dates != null) {
              projectDaysOnWeek = dates.size();
            }
            log.debug("Week Project length(modified): " + projectLength + " days");
            log.debug("Week Project days:" + projectDaysOnWeek);
            log.debug(
                "Week Project effort per day: " + new AFTime(sum.getTime() / (long) projectLength));
            sum = new AFTime((sum.getTime() / (long) projectLength) * projectDaysOnWeek);
            if (sum != null) {
              total.add(sum);
              log.debug("Week effort sum: " + sum);
            }
          }
        }
      }

      effortLefts.put(week, total.toString());
      start = cUtils.nextMonday(start);
      end = cUtils.nextMonday(start);
      cal.setTime(start);
      week = cal.get(GregorianCalendar.WEEK_OF_YEAR);
    }

    return effortLefts;
  }
  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);
  }