/******************************************************************************************************************* * * Reacts to the notification that a {@link Project} has been selected by populating the presentation with * its job events. * * @param event the notification event * ******************************************************************************************************************/ @VisibleForTesting void onProjectSelectedEvent (final @Nonnull @ListensTo ProjectSelectedEvent event) { log.info("onProjectSelectedEvent({})", event); presentation.populate(event.getProject().findChildren() .stream() .map(jobEvent -> (JobEventSpi)jobEvent) .sorted(comparing(JobEventSpi::getDateTime)) .map(jobEvent -> jobEvent.as(Presentable).createPresentationModel()) .collect(toCompositePresentationModel())); } }
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"); // TODO: quick and dirty - refactor with visitor, lambdas 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())); // FIXME: rename getAmount() -> getBudget() // FIXME: introduce getBudgetDuration() 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(); }
final @Nonnull String prefix) List<? extends JobEvent> jobEvents = project.findChildren().results(); int x = jobEvents.size() / (invoiceCount + 1);
/******************************************************************************************************************* * * Retrieves the hourly rates - if missing from the project description, tries to recover it from the first * meaningful job event. * ******************************************************************************************************************/ @Nonnull private Money getHourlyRate(final ConfigurationDecorator projectConfig, final List<JobEvent> jobEvents) throws NotFoundException { Money hourlyRate = projectConfig.getMoney("projectRate"); if ((hourlyRate.compareTo(Money.ZERO) == 0) && !jobEvents.isEmpty()) // don't use equals() - see http://stackoverflow.com/questions/6787142/bigdecimal-equals-versus-compareto { JobEvent event = jobEvents.get(0); while ((event instanceof JobEventGroup) && ((JobEventGroup)event).findChildren().count() > 0) { event = ((JobEventGroup)event).findChildren().firstResult(); } if (event instanceof TimedJobEventSpi) { hourlyRate = ((TimedJobEventSpi)event).getHourlyRate(); } } return hourlyRate; }
private void addAll (final @Nonnull List<JobEventSpi> results, final @Nonnull List<? extends JobEvent> jobEvents) { for (final JobEvent jobEvent : jobEvents) { if (jobEvent instanceof JobEventGroup) { addAll(results, ((JobEventGroup)jobEvent).findChildren().results()); } else { results.add((JobEventSpi)jobEvent); } } } }
public ProjectXml (final @Nonnull Project project) { final Project.Builder builder = project.toBuilder(); this.id = builder.getId(); this.customerXml = new CustomerXml(builder.getCustomer()); this.name = builder.getName(); this.number = builder.getNumber(); this.description = builder.getDescription(); this.notes = builder.getNotes(); this.status = builder.getStatus(); this.hourlyRate = builder.getHourlyRate(); this.budget = builder.getBudget(); this.startDate = builder.getStartDate(); this.endDate = builder.getEndDate(); this.jobEventsXml = project.findChildren().stream().map(jobEvent -> new JobEventXml(jobEvent)).collect(toList()); }
@Override @Nonnull public PresentationModel createPresentationModel (final @Nonnull Object... instanceRoles) { final Styleable styleable = new DefaultStyleable(getStyles()); return jobEvent.findChildren() .stream() .map(jobEvent -> (JobEventSpi)jobEvent) .sorted(comparing(JobEventSpi::getDateTime)) .map(jobEvent -> jobEvent.as(Presentable).createPresentationModel()) .collect(toCompositePresentationModel(aggregateBuilder().create(), styleable)); // FIXME: use SimpleCompositePresentable? }