use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class HierarchySynchronizer method mergeSchedules.
private void mergeSchedules(EVSchedule currentSchedule, EVSchedule lastSyncedSchedule, double syncPdt) {
// look at the three schedule end dates, and determine when the merged
// schedule should end.
int currentEndWeek = getEndWeekOfSchedule(currentSchedule, startDate);
int syncedEndWeek = getEndWeekOfSchedule(lastSyncedSchedule, startDate);
int mergedEndWeek;
if (currentEndWeek == syncedEndWeek)
mergedEndWeek = endWeek;
else
mergedEndWeek = currentEndWeek;
// Keep a list of manual edits the user has made, for reverse sync
Map<Date, Double> userExceptions = new HashMap<Date, Double>();
// Make a list of "merged exceptions." Begin with the ones that came
// from the current WBS.
Map mergedExceptions = new HashMap(scheduleExceptions);
// manually after receiving the last schedule from the WBS.
for (int i = 0; i < currentSchedule.getRowCount(); i++) {
Period c = currentSchedule.get(i + 1);
// we can stop looking for manual edits
if (c.isAutomatic())
break;
Date beg = c.getBeginDate();
Date end = c.getEndDate();
long midTime = (beg.getTime() + end.getTime()) / 2;
Date mid = new Date(midTime);
// if the time in this period matches the value that came from the
// last synced schedule, it isn't a manual edit.
double currentTime = c.planDirectTime();
Period s = lastSyncedSchedule.get(mid);
if (s != null && eq(s.planDirectTime(), currentTime))
continue;
// if the manual edit happened in a week that preceeds the start or
// follows the end of our new schedule, it isn't relevant.
int week = (int) ((midTime - startDate.getTime()) / WEEK_MILLIS);
if (week < 0)
continue;
if (mergedEndWeek != -1 && week >= mergedEndWeek)
continue;
if (eq(currentTime, syncPdt)) {
// the user erased an exception that they received from the
// WBS. We should do the same thing for the new WBS data.
mergedExceptions.remove(week);
userExceptions.put(mid, null);
} else {
// the user created a new exception in the schedule. Add it
// to our map.
Double hours = new Double(currentTime / 60.0);
mergedExceptions.put(week, hours);
userExceptions.put(mid, hours);
}
}
// build a schedule from the information we've merged, and reset the
// current schedule to use that information.
double levelOfEffort = currentSchedule.getLevelOfEffort();
EVSchedule mergedSchedule = new EVSchedule(startDate, hoursPerWeek, mergedEndWeek, mergedExceptions, levelOfEffort, true);
currentSchedule.copyFrom(mergedSchedule);
// save information about user edits for delivery to the WBS
if (!userExceptions.isEmpty())
discrepancies.add(new SyncDiscrepancy.EVSchedule(userExceptions));
}
use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class EVReport method writeValueTable2.
public void writeValueTable2() {
if (evModel != null) {
EVSchedule s = evModel.getSchedule();
int maxSeries = 3;
if (s instanceof EVScheduleRollup)
maxSeries = 4;
writeChartData(s.getValueChartData(), maxSeries);
} else
writeFakeChartData("Plan", "Actual", "Forecast", "Optimized");
}
use of net.sourceforge.processdash.ev.EVSchedule in project processdash by dtuma.
the class EVReport method writeHTML.
/** Generate a page of HTML displaying the Task and Schedule templates,
* and including img tags referencing charts.
*/
public void writeHTML() throws IOException {
isSnippet = (env.containsKey(SnippetEnvironment.SNIPPET_ID));
String namespace = (isSnippet ? "$$$_" : "");
String taskListDisplayName = EVTaskList.cleanupName(taskListName);
String taskListHTML = HTMLUtils.escapeEntities(taskListDisplayName);
String title = resources.format("Report.Title_FMT", taskListHTML);
EVTaskFilter taskFilter = settings.getEffectiveFilter(evModel);
EVSchedule s = getEvSchedule(taskFilter);
EVTaskDataWriter taskDataWriter = getEffectiveTaskDataWriter();
StringBuffer header = new StringBuffer(HEADER_HTML);
StringUtils.findAndReplace(header, TITLE_VAR, title);
if (taskFilter != null && isSnippet == false)
header.append(FILTER_HEADER_HTML);
out.print(header);
out.print(taskDataWriter.getHeaderItems());
out.print("</head><body>");
out.print(isSnippet ? "<h2>" : "<h1>");
out.print(title);
if (!exportingToExcel()) {
interpOutLink(SHOW_WEEK_LINK, EVReportSettings.PURPOSE_WEEK);
interpOutLink(SHOW_MONTH_LINK, EVReportSettings.PURPOSE_WEEK);
printAlternateViewLinks();
interpOutLink(SHOW_CHARTS_LINK, EVReportSettings.PURPOSE_OTHER);
}
printCustomizationLink();
out.print(isSnippet ? "</h2>" : "</h1>");
if (!isSnippet)
printFilterInfo(out, taskFilter, settings, isExporting(), exportingToExcel());
if (!exportingToExcel()) {
writeImageHtml(taskFilter != null);
out.print("<div style='clear:both'></div>");
writeCharts(evModel, s, taskFilter, settings.getBool(CUSTOMIZE_HIDE_NAMES), 350, 300, ChartListPurpose.ReportMain, null, null);
out.print("<div style='clear:both'> </div>");
out.print(HTMLTreeTableWriter.TREE_ICON_HEADER);
}
EVMetrics m = s.getMetrics();
printScheduleErrors(out, m.getErrors());
boolean hidePlan = settings.getBool(CUSTOMIZE_HIDE_PLAN_LINE);
boolean hideReplan = settings.getBool(CUSTOMIZE_HIDE_REPLAN_LINE);
boolean hideForecast = settings.getBool(CUSTOMIZE_HIDE_FORECAST_LINE);
out.print("<table name='STATS'>");
for (int i = 0; i < m.getRowCount(); i++) writeMetric(m, i, hidePlan, hideReplan, hideForecast);
out.print("</table>");
out.print("<h2><a name='" + namespace + "tasks'></a>" + getResource("TaskList.Title"));
printTaskStyleLinks(taskDataWriter, namespace);
out.print("</h2>\n");
taskDataWriter.write(out, evModel, taskFilter, settings, namespace);
out.print("<h2>" + getResource("Schedule.Title") + "</h2>\n");
writeScheduleTable(s);
if (isExporting() && !isSnippet)
writeExportFooter(out);
out.print("<p class='doNotPrint'>");
if (!isSnippet && !exportingToExcel())
interpOutLink(EXPORT_TEXT_LINK);
if (!parameters.containsKey("EXPORT")) {
if (taskFilter == null) {
interpOutLink(EXPORT_CHARTS_LINK);
interpOutLink(EXPORT_MSPROJ_LINK);
}
if (!isSnippet) {
String link = EXPORT_ARCHIVE_LINK;
String filenamePat = HTMLUtils.urlEncode(resources.getString("Report.Archive_Filename"));
link = StringUtils.findAndReplace(link, "FILENAME", filenamePat);
interpOutLink(link);
}
}
out.print("</p>");
out.print("</body></html>");
}
Aggregations