private void makeReport (final @Nonnull Writer w)
{
final PrintWriter pw = new PrintWriter(w);
System.err.println("CREATE REPORT " + project);
pw.printf(SEPARATOR + "\n");
pw.printf(PATTERN, "Date", "Description", "Time", "Cost");
pw.printf(SEPARATOR + "\n");
final List<JobEventSpi> jobEvents = new ArrayList<>();
addAll(jobEvents, project.findChildren().results());
jobEvents.stream().sorted(comparing(JobEventSpi::getDateTime))
.forEach(event -> pw.printf(PATTERN2, DATE_FORMATTER.format(event.getDateTime()),
event.getName(),
DURATION_FORMATTER.format(event.getDuration()),
MONEY_FORMATTER.format(event.getEarnings())));
pw.printf(SEPARATOR + "\n");
pw.printf(PATTERN3, "", "", DURATION_FORMATTER.format(project.getDuration()),
MONEY_FORMATTER.format(project.getEarnings()));
final Duration duration = Duration.ofHours((long)project.getBudget().divided(project.getHourlyRate()));
pw.printf("BUDGET: %s\n", MONEY_FORMATTER.format(project.getBudget()));
pw.printf("HOURLY RATE: %s\n", MONEY_FORMATTER.format(project.getHourlyRate()));
pw.printf("DURATION: %s\n", DURATION_FORMATTER.format(duration));
pw.printf("REMAINING BUDGET: %s\n", MONEY_FORMATTER.format(project.getBudget().subtract(project.getEarnings())));
pw.printf("REMAINING TIME: %s\n", DURATION_FORMATTER.format(duration.minus(project.getDuration())));
pw.flush();
}