use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class EVScheduleConfidenceIntervals method addIndivDateSamples.
private void addIndivDateSamples() {
for (int i = 0; i < randomObjects.size(); i++) {
Object o = randomObjects.get(i);
if (o instanceof EVSchedule) {
EVSchedule s = (EVSchedule) o;
Date forecast = s.getMetrics().independentForecastDate();
indivDates[i].addSample(getTime(forecast));
}
}
}
use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class EVWeekReport method writeReport.
private void writeReport(String taskListName, EVTaskList evModel, Date effDate, EVReportSettings settings, EVTaskFilter taskFilter, EVTaskListFilter privacyFilter, int purpose) throws IOException {
EVSchedule schedule = evModel.getSchedule();
double totalPlanTime = schedule.getMetrics().totalPlan();
boolean hideNames = settings.getBool(EVReport.CUSTOMIZE_HIDE_NAMES);
boolean showAssignedTo = (evModel instanceof EVTaskListRollup) && !hideNames;
boolean showTimingIcons = (evModel instanceof EVTaskListData && !isExporting() && purpose == PLAIN_REPORT);
boolean showMilestones = evModel.showMilestoneColumn();
boolean showLabels = evModel.showLabelsColumn();
int numOptionalCols = //
(showAssignedTo ? 1 : 0) + (showMilestones ? 1 : 0) + (showLabels ? 1 : 0);
boolean monthly = isMonthly(settings);
Resources effRes = (monthly ? monthRes : resources);
// Calculate the dates one week/month before and after the effective date.
Date lastWeek, nextWeek;
if (monthly) {
long eff = effDate.getTime();
lastWeek = roundToMonthEnd(new Date(eff - 5 * MILLIS_PER_WEEK));
nextWeek = roundToMonthEnd(new Date(eff + MILLIS_PER_WEEK));
} else {
lastWeek = adjustDate(effDate, -EVSchedule.WEEK_MILLIS);
nextWeek = adjustDate(effDate, EVSchedule.WEEK_MILLIS);
}
Date startDate = schedule.getStartDate();
if (lastWeek.before(startDate))
lastWeek = startDate;
Date effDateDisplay = new Date(effDate.getTime() - 1000);
Date nextWeekDisplay = new Date(nextWeek.getTime() - 1000);
// calculate flags describing whether the actual current date falls
// within our reporting period
long now = System.currentTimeMillis();
boolean reportingPeriodIncludesToday = (lastWeek.getTime() < now && now <= effDate.getTime());
boolean reportingPeriodPrecedesToday = (effDate.getTime() < now && now <= nextWeek.getTime());
// Calculate future cutoff dates for task dependency display
Date dependDate = getFutureCutoffDate(effDate, Settings.getInt("ev.numDependencyWeeks", monthly ? 5 : 3));
Date revDependDate = getFutureCutoffDate(effDate, Settings.getInt("ev.numReverseDependencyWeeks", 6));
// Get a slice of the schedule representing the previous week.
EVSchedule filteredSchedule = getEvSchedule(evModel, taskFilter);
EVSchedule.Period weekSlice = EVScheduleRollup.getSlice(filteredSchedule, lastWeek, effDate);
// Now scan the task list looking for information we need.
TableModel tasks = evModel.getSimpleTableModel(taskFilter);
int taskListLen = tasks.getRowCount();
// keep track of tasks that should be displayed in the three lists.
boolean[] completedLastWeek = new boolean[taskListLen];
boolean[] inProgressThisWeek = new boolean[taskListLen];
boolean[] dueThroughNextWeek = new boolean[taskListLen];
byte[] progress = new byte[taskListLen];
Map<String, DependencyForCoord> upcomingDependencies = new HashMap<String, DependencyForCoord>();
List<RevDependencyForCoord> reverseDependencies = new ArrayList<RevDependencyForCoord>();
Arrays.fill(completedLastWeek, false);
Arrays.fill(inProgressThisWeek, false);
Arrays.fill(dueThroughNextWeek, false);
boolean oneCompletedLastWeek = false;
boolean oneInProgressThisWeek = false;
boolean oneDueNextWeek = false;
// keep track of the people assigned to the current schedule
Set allIndividuals = new HashSet();
String ignoreIndividual = null;
if (evModel instanceof EVTaskListData && purpose == PLAIN_REPORT)
allIndividuals.add(ignoreIndividual = getOwner());
// retrieve information about the actual time that was logged to tasks
// during the effective time period
double[] actualTimeThisWeek = getActualTimeSpent(tasks, lastWeek, effDate);
double completedTasksTimeThisWeek = 0;
double inProgressTasksTimeThisWeek = 0;
// keep track of the two total plan/actual time to date for
// completed tasks.
double completedTasksTotalPlanTime = 0;
double completedTasksTotalActualTime = 0;
// keep track of plan and actual value, this week and to date
double planValueThisWeek = 0;
double valueEarnedThisWeek = 0;
double planValueToDate = 0;
double valueEarnedToDate = 0;
for (int i = 0; i < taskListLen; i++) {
double taskValue = parseTime(tasks.getValueAt(i, -EVTaskList.PLAN_DTIME_COLUMN));
Date completed = (Date) tasks.getValueAt(i, EVTaskList.DATE_COMPLETE_COLUMN);
// check to see if the task was due this week, or in the past
Date due = (Date) tasks.getValueAt(i, EVTaskList.PLAN_DATE_COLUMN);
if (due != null && due.before(effDate)) {
planValueToDate += taskValue;
if (!due.before(lastWeek))
planValueThisWeek += taskValue;
}
if (completed != null && completed.before(effDate)) {
completedTasksTotalPlanTime += taskValue;
completedTasksTotalActualTime += parseTime(tasks.getValueAt(i, -EVTaskList.ACT_DTIME_COLUMN));
valueEarnedToDate += taskValue;
if (!completed.before(lastWeek) && completed.before(nextWeek)) {
completedLastWeek[i] = oneCompletedLastWeek = true;
completedTasksTimeThisWeek += actualTimeThisWeek[i];
valueEarnedThisWeek += taskValue;
} else if (actualTimeThisWeek[i] > 0) {
// if the task was marked complete in the past, but
// someone logged time against it this week, display
// it in the "in progress" table.
inProgressThisWeek[i] = oneInProgressThisWeek = true;
inProgressTasksTimeThisWeek += actualTimeThisWeek[i];
}
} else {
Date replannedDue = (Date) tasks.getValueAt(i, EVTaskList.REPLAN_DATE_COLUMN);
Date taskStarted = (Date) tasks.getValueAt(i, EVTaskList.ACT_START_DATE_COLUMN);
// Check to see if the task was in progress this week
if (taskStarted != null && taskStarted.before(effDate) && (completed == null || completed.after(effDate))) {
inProgressThisWeek[i] = oneInProgressThisWeek = true;
inProgressTasksTimeThisWeek += actualTimeThisWeek[i];
}
// Check to see if the task is due next week
if ((due != null && due.after(startDate) && due.before(nextWeek)) || (replannedDue != null && replannedDue.after(startDate) && replannedDue.before(nextWeek))) {
dueThroughNextWeek[i] = oneDueNextWeek = true;
}
if ((inProgressThisWeek[i] || dueThroughNextWeek[i]) && (due != null)) {
if (!due.after(effDate))
progress[i] = BEHIND_SCHEDULE;
else if (due.after(nextWeek))
progress[i] = AHEAD_OF_SCHEDULE;
}
Date projectedDate = (Date) tasks.getValueAt(i, EVTaskList.PROJ_DATE_COLUMN);
findUpcomingDependencies(tasks, upcomingDependencies, i, projectedDate, dependDate, ignoreIndividual);
// point in collecting reverse dependencies.
if (!hideNames)
findReverseDependencies(tasks, reverseDependencies, revDependDate, i);
}
List assignedTo = (List) tasks.getValueAt(i, -EVTaskList.ASSIGNED_TO_COLUMN);
if (assignedTo != null)
allIndividuals.addAll(assignedTo);
}
double cpi = completedTasksTotalPlanTime / completedTasksTotalActualTime;
boolean showTimeThisWeek = (completedTasksTimeThisWeek > 0 || inProgressTasksTimeThisWeek > 0);
// look up planned values from the schedule, if appropriate
if (!monthly || Settings.getBool("ev.month.extrapolatePV", true)) {
planValueThisWeek = weekSlice.planValue();
planValueToDate = weekSlice.getCumPlanValue();
}
// look up earned values from the schedule, if not in monthly mode
if (!monthly) {
valueEarnedThisWeek = weekSlice.earnedValue();
valueEarnedToDate = weekSlice.getCumEarnedValue();
}
if (isTopLevel(purpose)) {
String taskListDisplayName = EVTaskList.cleanupName(taskListName);
String titleHTML = effRes.format("Title_FMT", taskListDisplayName);
titleHTML = HTMLUtils.escapeEntities(titleHTML);
StringBuffer header = new StringBuffer(HEADER_HTML);
StringUtils.findAndReplace(header, TITLE_VAR, titleHTML);
if (taskFilter != null)
header.insert(header.indexOf("</head>"), FILTER_HEADER_HTML);
if (isExportingToExcel())
StringUtils.findAndReplace(header, "hideIfCollapsed", "ignore");
out.print(header);
out.print("<h2>");
String endDateStr = monthly ? formatMonth(effDateDisplay) : encodeHTML(effDateDisplay);
out.print(effRes.format("Header_HTML_FMT", endDateStr));
if (!isExporting() || getParameter(EFF_DATE_PARAM) == null) {
if (lastWeek.compareTo(startDate) > 0)
printNavLink(lastWeek, "Previous", settings, purpose);
printNavLink(nextWeek, "Next", settings, purpose);
if (!isExporting())
printGoToDateLink(effDate, schedule, settings, purpose);
}
out.print("</h2>\n");
EVReport.printFilterInfo(out, taskFilter, settings, isExporting(), isExportingToExcel());
EVReport.printScheduleErrors(out, filteredSchedule.getMetrics().getErrors());
} else {
out.print("<div class='");
out.print(purpose == LEAF_REPORT ? "collapsed" : "expanded");
out.print("'><h2>");
printExpansionIcon();
out.print(encodeHTML(taskListName));
out.print("</h2>\n");
out.print("<div class='subsection");
if (purpose != LEAF_REPORT)
out.print(" hideIfCollapsed");
out.print("'>");
}
String indivDetail = "";
if (purpose == LEAF_REPORT)
indivDetail = " class='hideIfCollapsed'";
String hh = (purpose == SPLIT_REPORT ? "h2" : "h3");
String personalDataID = evModel.getPersonalDataID();
boolean shouldHideSummary = (privacyFilter != null && personalDataID != null && privacyFilter.include(personalDataID) == false);
if (!shouldHideSummary) {
interpOut("<" + hh + indivDetail + ">${Summary.Header}");
if (isTopLevel(purpose) && showAssignedTo && !isExporting()) {
String splitLink = (String) env.get("REQUEST_URI");
if (purpose == PLAIN_REPORT)
splitLink = HTMLUtils.appendQuery(splitLink, SPLIT_PARAM, "t");
else
splitLink = HTMLUtils.removeParam(splitLink, SPLIT_PARAM);
out.print(" <span class='nav'><a href='");
out.print(splitLink);
out.print("'>");
out.print(resources.getHTML(purpose == PLAIN_REPORT ? "Show_Split" : "Show_Rollup"));
out.print("</a></span>");
}
out.print("</" + hh + ">");
out.print("<table border=1 name='summary'><tr><td></td><td></td>");
if (taskFilter == null)
interpOut("<td class=header colspan=3>${Summary.Direct_Hours}" + "</td><td></td>");
interpOut("<td class=header colspan=3>${Summary.Earned_Value}" + //
"</td></tr>\n" + "<tr><td></td><td></td>");
if (taskFilter == null)
interpOut("<td class=header>${Summary.Plan}</td>" + "<td class=header>${Summary.Actual}</td>" + "<td class=header>${Summary.Ratio}</td><td></td>");
interpOut("<td class=header>${Summary.Plan}</td>" + "<td class=header>${Summary.Actual}</td>" + "<td class=header>${Summary.Ratio}</td></tr>\n");
String thisWeekKey;
String keySuffix = (monthly ? "_Month" : "_Week");
if (reportingPeriodIncludesToday)
thisWeekKey = "This" + keySuffix;
else if (reportingPeriodPrecedesToday)
thisWeekKey = "Last" + keySuffix;
else
thisWeekKey = "This_Period";
out.print("<tr><td class=left>" + effRes.getHTML("Summary." + thisWeekKey) + "</td><td></td>");
if (taskFilter == null) {
double directTimeThisWeek;
if (monthly)
directTimeThisWeek = sumActualTime(actualTimeThisWeek);
else
directTimeThisWeek = weekSlice.getActualDirectTime();
printTimeData(weekSlice.getPlanDirectTime(), directTimeThisWeek);
out.print("<td></td>");
}
printPctData(//
planValueThisWeek / totalPlanTime, valueEarnedThisWeek / totalPlanTime);
out.print("</tr>\n");
out.print("<tr><td class=left>" + encodeHTML(resources.format("Summary.To_Date_FMT", effDateDisplay)) + "</td><td></td>");
double directTimeToDate = 0;
if (taskFilter == null) {
if (monthly)
directTimeToDate = schedule.get(0).getActualDirectTime() + sumActualTime(getActualTimeSpent(tasks, startDate, effDate));
else
directTimeToDate = weekSlice.getCumActualDirectTime();
printTimeData(weekSlice.getCumPlanDirectTime(), directTimeToDate);
out.print("<td></td>");
}
printPctData(//
planValueToDate / totalPlanTime, valueEarnedToDate / totalPlanTime);
out.print("</tr>\n");
double numWeeks = Double.NaN;
if (startDate != null)
numWeeks = (effDate.getTime() - startDate.getTime() - EVSchedule.dstDifference(startDate.getTime(), effDate.getTime())) / (double) MILLIS_PER_WEEK;
if (monthly) {
numWeeks = numWeeks / WEEKS_PER_MONTH;
interpOut("<tr" + indivDetail + "><td class=left>" + "${Month.Summary.Average_per_Month}</td><td></td>");
} else {
interpOut("<tr" + indivDetail + "><td class=left>${Summary.Average_per_Week}</td><td></td>");
}
if (taskFilter == null) {
double planTimePerWeek = weekSlice.getCumPlanDirectTime() / numWeeks;
double actualTimePerWeek = directTimeToDate / numWeeks;
printTimeData(planTimePerWeek, actualTimePerWeek);
out.print("<td></td>");
}
double planEVPerWeek = planValueToDate / (totalPlanTime * numWeeks);
double actualEVPerWeek = valueEarnedToDate / (totalPlanTime * numWeeks);
printPctData(planEVPerWeek, actualEVPerWeek);
out.print("</tr>\n");
if (taskFilter == null) {
interpOut("<tr" + indivDetail + "><td class=left>${Summary.Completed_Tasks_To_Date}" + "</td><td></td>");
printData(formatTime(completedTasksTotalPlanTime), formatTime(completedTasksTotalActualTime), 1.0 / cpi, "timeFmt");
out.print("<td></td><td></td><td></td><td></td></tr>\n");
}
out.print("</table>\n");
}
if (purpose == PLAIN_REPORT || purpose == LEAF_REPORT) {
out.print("<div class='hideIfCollapsed'>\n");
// create a table writer with appropriate renderers.
HTMLTableWriter tableWriter = createTableWriter(evModel, hideNames, showTimingIcons);
// to draw the completed tasks table, remove the "task with timing
// icons" renderer if it happens to be in use.
HTMLTableWriter.CellRenderer taskRenderer = tableWriter.getCellRenderer(EVTaskList.TASK_COLUMN);
tableWriter.setCellRenderer(EVTaskList.TASK_COLUMN, EVReport.EV_CELL_RENDERER);
String completedTasksTooltip = encodeHTML(resources.format("Completed_Tasks.Header_Tip_FMT", lastWeek, effDateDisplay));
String completedTasksHeader;
if (reportingPeriodIncludesToday)
completedTasksHeader = effRes.getHTML("Completed_Tasks.Header");
else if (reportingPeriodPrecedesToday)
completedTasksHeader = effRes.getHTML("Completed_Tasks.Header_Last");
else if (monthly)
completedTasksHeader = effRes.format("Completed_Tasks.Header_Month_HTML_FMT", formatMonth(effDateDisplay));
else
completedTasksHeader = completedTasksTooltip;
out.print("<h3 title='" + completedTasksTooltip + "'>" + completedTasksHeader + "</h3>\n");
if (!oneCompletedLastWeek)
interpOut("<p><i>${None}</i>\n");
else {
printCompletedTaskTableHeader(showTimeThisWeek, showAssignedTo, showMilestones, showLabels, monthly);
double totalPlannedTime = 0;
double totalActualTime = 0;
double totalPlannedValue = 0;
for (int i = 0; i < taskListLen; i++) {
if (!completedLastWeek[i])
continue;
double taskPlannedTime = parseTime(tasks.getValueAt(i, -EVTaskList.PLAN_TIME_COLUMN));
double taskActualTime = parseTime(tasks.getValueAt(i, -EVTaskList.ACT_TIME_COLUMN));
double taskPlannedValue = ((Double) tasks.getValueAt(i, -EVTaskList.PLAN_VALUE_COLUMN)).doubleValue();
totalPlannedTime += taskPlannedTime;
totalActualTime += taskActualTime;
totalPlannedValue += taskPlannedValue;
printCompletedLine(tableWriter, tasks, i, showTimeThisWeek ? actualTimeThisWeek : null, showAssignedTo, showMilestones, showLabels);
}
interpOut("<tr class='sortbottom'><td><b>${Completed_Tasks.Total}" + " </b></td><td class='timeFmt'>");
out.print(formatTime(totalPlannedTime) + "</td>");
out.print("<td class='timeFmt'>");
out.print(formatTime(totalActualTime) + "</td>");
if (showTimeThisWeek) {
out.print("<td class='timeFmt'>");
out.print(formatTime(completedTasksTimeThisWeek) + "</td>");
}
if (totalPlannedTime > 0) {
double totalPctSpent = totalActualTime / totalPlannedTime;
out.print("<td>" + EVSchedule.formatPercent(totalPctSpent) + "</td>");
} else {
out.print("<td> </td>");
}
// Empty td for assigned to, planned date, and labels columns
int noSumCol = 1 + numOptionalCols;
for (int i = 0; i < noSumCol; ++i) out.print("<td> </td>");
out.print("<td>" + EVSchedule.formatPercent(totalPlannedValue) + "</td></tr>\n");
out.println("</table>");
}
// put the "task with timing icons" renderer back in place if necessary
tableWriter.setCellRenderer(EVTaskList.TASK_COLUMN, taskRenderer);
String inProgressTooltip = encodeHTML(resources.format("Tasks_In_Progress.Header_Tip_FMT", effDateDisplay));
String inProgressHeader;
if (reportingPeriodIncludesToday || reportingPeriodPrecedesToday)
inProgressHeader = effRes.getHTML("Tasks_In_Progress.Header");
else
inProgressHeader = encodeHTML(resources.format("Tasks_In_Progress.Header_Long_FMT", effDateDisplay));
out.print("<h3 title='" + inProgressTooltip + "'>" + inProgressHeader + "</h3>\n");
if (!oneInProgressThisWeek)
interpOut("<p><i>${None}</i>\n");
else {
printUncompletedTaskTableHeader(showTimeThisWeek, showAssignedTo, showMilestones, showLabels, true, monthly);
double totalPlannedTime = 0;
double totalActualTime = 0;
double totalPlannedValue = 0;
double totalPlannedTimeRemaining = 0;
double totalUnearnedValue = 0;
for (int i = 0; i < taskListLen; ++i) {
if (!inProgressThisWeek[i])
continue;
double taskPlannedTime = parseTime(tasks.getValueAt(i, -EVTaskList.PLAN_TIME_COLUMN));
double taskActualTime = parseTime(tasks.getValueAt(i, -EVTaskList.ACT_TIME_COLUMN));
double taskPlannedValue = ((Double) tasks.getValueAt(i, -EVTaskList.PLAN_VALUE_COLUMN)).doubleValue();
double taskPlannedTimeRemaining = taskPlannedTime - taskActualTime;
double taskUnearnedValue = computeUnearnedValue(tasks, i);
totalPlannedTime += taskPlannedTime;
totalActualTime += taskActualTime;
totalPlannedValue += taskPlannedValue;
totalPlannedTimeRemaining += (taskPlannedTimeRemaining > 0) ? taskPlannedTimeRemaining : 0;
totalUnearnedValue += taskUnearnedValue;
printInProgressLine(tableWriter, tasks, progress[i], i, taskPlannedTimeRemaining, showTimeThisWeek ? actualTimeThisWeek : null, showAssignedTo, showMilestones, showLabels, taskUnearnedValue);
}
interpOut("<tr class='sortbottom'><td><b>${Tasks_In_Progress.Total}" + " </b></td><td class='timeFmt'>");
out.print(formatTime(totalPlannedTime) + "</td>");
out.print("<td class='timeFmt'>");
out.print(formatTime(totalActualTime) + "</td>");
if (showTimeThisWeek) {
out.print("<td class='timeFmt'>");
out.print(formatTime(inProgressTasksTimeThisWeek) + "</td>");
}
out.print("<td>" + EVSchedule.formatPercent(totalPlannedValue) + "</td>");
if (totalPlannedTime > 0) {
double totalPctSpent = totalActualTime / totalPlannedTime;
out.print("<td>" + EVSchedule.formatPercent(totalPctSpent) + "</td>");
} else {
out.print("<td> </td>");
}
// Empty td because there is no total for Planned Date and Dep.
int noSumCol = 2 + numOptionalCols;
for (int i = 0; i < noSumCol; ++i) out.print("<td> </td>");
out.print("<td class='timeFmt'>");
out.print(formatTime(totalPlannedTimeRemaining) + "</td>");
out.println("<td>" + EVSchedule.formatPercent(totalUnearnedValue) + "</td>");
out.println("</tr>\n</table>");
}
String dueTasksTooltip = encodeHTML(resources.format("Due_Tasks.Header_Tip_FMT", effDateDisplay, nextWeekDisplay));
String dueTasksHeader;
if (reportingPeriodIncludesToday)
dueTasksHeader = effRes.getHTML("Due_Tasks.Header");
else if (reportingPeriodPrecedesToday)
dueTasksHeader = effRes.getHTML("Due_Tasks.Header_This");
else
dueTasksHeader = encodeHTML(resources.format("Due_Tasks.Header_Long_FMT", nextWeekDisplay));
out.print("<h3 title='" + dueTasksTooltip + "'>" + dueTasksHeader + "</h3>\n");
if (!oneDueNextWeek)
interpOut("<p><i>${None}</i>\n");
else {
printUncompletedTaskTableHeader(false, showAssignedTo, showMilestones, showLabels, false, monthly);
double timeRemaining = 0;
for (int i = 0; i < taskListLen; i++) if (dueThroughNextWeek[i]) {
double forecastTimeRemaining = computeTaskForecastTimeRemaining(tasks, i, cpi);
printDueLine(tableWriter, tasks, progress[i], i, cpi, forecastTimeRemaining, showAssignedTo, showMilestones, showLabels);
if (progress[i] != AHEAD_OF_SCHEDULE && forecastTimeRemaining > 0)
timeRemaining += forecastTimeRemaining;
}
out.print("<tr class='sortbottom'><td align=right colspan=");
int colspan = 6 + numOptionalCols;
out.print(Integer.toString(colspan));
interpOut("><b>${Due_Tasks.Total}" + " </b></td><td class='timeFmt'>");
out.print(formatTime(timeRemaining));
out.println("</td></tr>\n</table>");
}
out.print("</div>\n");
} else {
EVTaskListRollup parentEVModel = (EVTaskListRollup) evModel;
for (int i = 0; i < parentEVModel.getSubScheduleCount(); i++) {
EVTaskList childModel = parentEVModel.getSubSchedule(i);
String childName = EVTaskList.cleanupName(childModel.getTaskListName());
int childPurpose = (childModel instanceof EVTaskListRollup ? SUB_REPORT : LEAF_REPORT);
writeReport(childName, childModel, effDate, settings, taskFilter, privacyFilter, childPurpose);
}
}
if (!isTopLevel(purpose)) {
// end the "subsection" div we started earlier.
out.print("</div></div>");
} else {
interpOut("<" + hh + ">${Dependencies.Header}</" + hh + ">\n");
discardInternalReverseDependencies(upcomingDependencies, reverseDependencies, allIndividuals);
if (upcomingDependencies.isEmpty() && reverseDependencies.isEmpty())
interpOut("<p><i>${None}</i>\n");
else {
if (!hideNames && !reverseDependencies.isEmpty())
printReverseDependencyTable(tasks, reverseDependencies, showAssignedTo);
List<DependencyForCoord> depsForCoord = new ArrayList<DependencyForCoord>(upcomingDependencies.values());
Collections.sort(depsForCoord);
int pos = 0;
for (DependencyForCoord coord : depsForCoord) {
printUpcomingDependencies(coord, tasks, showAssignedTo, hideNames, showMilestones, showLabels, pos++);
}
}
if (isExporting())
EVReport.writeExportFooter(out);
if (!isExportingToExcel())
interpOut(EXPORT_HTML);
out.print(FOOTER_HTML);
}
}
use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class EVReport method writeChartsPage.
protected void writeChartsPage() {
String taskListDisplayName = EVTaskList.cleanupName(taskListName);
String taskListHTML = HTMLUtils.escapeEntities(taskListDisplayName);
String title = resources.format("Report.Charts_Title_FMT", taskListHTML);
EVTaskFilter taskFilter = settings.getEffectiveFilter(evModel);
boolean hideNames = settings.getBool(CUSTOMIZE_HIDE_NAMES);
StringBuffer header = new StringBuffer(SIMPLE_HEADER_HTML);
StringUtils.findAndReplace(header, TITLE_VAR, title);
if (taskFilter != null)
header.append(FILTER_HEADER_HTML);
out.print(header);
out.print("</head><body>");
out.print("<h1>");
out.print(title);
out.print("</h1>");
printFilterInfo(out, taskFilter, settings, false, false);
EVSchedule s = getEvSchedule(taskFilter);
String singleChartId = getParameter(SINGLE_CHART_PARAM);
if (singleChartId == null)
writeChartsGalleryPage(taskFilter, hideNames, s);
else
writeSingleChartPage(taskFilter, hideNames, s, singleChartId);
out.print("</body></html>\n");
}
use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class TimeRatioMemberTrackingChartData method recalc.
public void recalc() {
clearSeries();
// see if the user has permission to view personal data in this chart
UserFilter f = GroupPermission.getGrantedMembers(permissionID);
if (f == null)
return;
EVTaskListFilter pf = new EVTaskListGroupFilter(f);
MemberChartNameHelper nameHelper = new MemberChartNameHelper(rollup);
for (int i = 0; i < rollup.getSubScheduleCount(); i++) {
EVTaskList tl = rollup.getSubSchedule(i);
String personalDataID = tl.getPersonalDataID();
if (personalDataID != null && !pf.include(personalDataID))
continue;
EVSchedule subsched = tl.getSchedule();
String seriesName = nameHelper.get(tl);
maybeAddSeries(subsched.getTimeRatioTrackingChartSeries(seriesName, maxDataPoints));
}
}
use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class HierarchySynchronizer method syncSchedule.
/** If we are synchronizing a project for an individual, and that
* individual has not edited their earned value schedule yet, sync
* the initial period in their earned value schedule to reflect the
* information entered in the team plan.
*/
private void syncSchedule() {
// only operate on individual schedules.
if (isTeam())
return;
// if no schedule information was found, there is nothing to do.
if (startDate == null && hoursPerWeek == 0)
return;
// look up the name of the EV schedule for the individual. If we
// don't find a valid/existing schedule name, abort.
List names = EVTaskList.getPreferredTaskListsForPath(dataRepository, projectPath);
if (names == null || names.size() != 1)
return;
String taskListName = (String) names.get(0);
if (!EVTaskListData.validName(taskListName))
return;
if (!EVTaskListData.exists(dataRepository, taskListName))
return;
// open the schedule.
EVTaskListData tl = new EVTaskListData(taskListName, dataRepository, hierarchy, false);
EVSchedule currentSchedule = tl.getSchedule();
// schedule for future use.
if (tl.getID() != null) {
forceData(projectPath, TeamDataConstants.PROJECT_SCHEDULE_NAME, StringData.create(taskListName));
forceData(projectPath, TeamDataConstants.PROJECT_SCHEDULE_ID, StringData.create(tl.getID()));
}
// see if it is OK for us to change this schedule. If the dates are
// locked, then we must have created it, so we can change it.
// Otherwise, if it looks like a default schedule (only one manual row),
// it is fine to replace it.
boolean isLocked = currentSchedule.areDatesLocked();
boolean isDefault = (currentSchedule.getRowCount() == 1 || currentSchedule.get(2).isAutomatic());
if (!isLocked && !isDefault)
return;
// construct a schedule according to the specifications in the WBS.
EVSchedule wbsSchedule = new EVSchedule(startDate, hoursPerWeek, endWeek, scheduleExceptions, currentSchedule.getLevelOfEffort(), true);
// retrieve information about the last values we synced to the schedule
ListData lastSyncedHoursList = asListData(tl.getMetadata(TeamDataConstants.PROJECT_SCHEDULE_SYNC_SCHEDULE));
double syncPdt = asDouble(tl.getMetadata(TeamDataConstants.PROJECT_SCHEDULE_SYNC_PDT));
// flags to keep track of what changes are made.
boolean madeChange = false;
boolean needSyncUpdate = false;
if (isDefault || lastSyncedHoursList == null) {
if (!currentSchedule.isEquivalentTo(wbsSchedule)) {
currentSchedule.copyFrom(wbsSchedule);
madeChange = true;
}
needSyncUpdate = true;
} else {
EVSchedule lastSyncedSchedule = new EVSchedule(lastSyncedHoursList, true);
EVSchedule origSchedule = currentSchedule.copy();
mergeSchedules(currentSchedule, lastSyncedSchedule, syncPdt);
if (wbsSchedule.isEquivalentTo(lastSyncedSchedule))
// the wbs schedule hasn't changed since our last sync, so
// there are no new changes to incorporate. (Note that it
// was still necessary for us to call mergeSchedules though,
// to compute the list of user discrepancies for reverse sync)
madeChange = false;
else if (origSchedule.isEquivalentTo(currentSchedule))
// no changes were made to the schedule, but we still need
// to update the sync data.
needSyncUpdate = true;
else
madeChange = needSyncUpdate = true;
}
// make certain the dates in the schedule are locked
if (!currentSchedule.areDatesLocked()) {
currentSchedule.setDatesLocked(true);
madeChange = true;
}
// save the "last synced hours" value for future reference
tl.setMetadata(TeamDataConstants.PROJECT_SCHEDULE_SYNC_SCHEDULE, wbsSchedule.getSaveList().formatClean());
// save the "last synced pdt" value for future reference
tl.setMetadata(TeamDataConstants.PROJECT_SCHEDULE_SYNC_PDT, Double.toString(hoursPerWeek * 60));
if (madeChange) {
// record the timezone that we've used to sync the schedule
String tz = TimeZone.getDefault().getID();
tl.setMetadata(EVMetadata.TimeZone.ID, tz);
// save the task list
if (!whatIfMode)
tl.save();
changes.add("Updated the earned value schedule");
} else if (needSyncUpdate) {
// no changes were made, but we need to save sync data. It's OK to
// do this, even in what-if mode.
tl.saveMetadata();
}
}
Aggregations