ProjectPresentable.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * blueHour: open source accounting
  5.  * http://tidalwave.it/projects/bluehour
  6.  *
  7.  * Copyright (C) 2013 - 2024 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/bluehour-src
  22.  * git clone https://github.com/tidalwave-it/bluehour-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.accounting.ui.projectexplorer.impl;

  27. import javax.annotation.Nonnull;
  28. import java.util.Collection;
  29. import it.tidalwave.accounting.model.spi.CustomerSpi;
  30. import it.tidalwave.accounting.model.spi.ProjectSpi;
  31. import it.tidalwave.accounting.model.types.Money;
  32. import it.tidalwave.role.Aggregate;
  33. import it.tidalwave.role.ui.Displayable;
  34. import it.tidalwave.role.ui.Presentable;
  35. import it.tidalwave.role.ui.PresentationModel;
  36. import it.tidalwave.role.ui.PresentationModelAggregate;
  37. import it.tidalwave.role.ui.Styleable;
  38. import it.tidalwave.dci.annotation.DciRole;
  39. import lombok.RequiredArgsConstructor;
  40. import static it.tidalwave.accounting.commons.Styleables.RIGHT_ALIGNED;
  41. import static it.tidalwave.accounting.model.spi.util.Formatters.*;
  42. import static it.tidalwave.util.Parameters.r;

  43. /***************************************************************************************************************************************************************
  44.  *
  45.  * @author  Fabrizio Giudici
  46.  *
  47.  **************************************************************************************************************************************************************/
  48. @DciRole(datumType = ProjectSpi.class)
  49. @RequiredArgsConstructor
  50. public class ProjectPresentable implements Presentable
  51.   {
  52.     @Nonnull
  53.     private final ProjectSpi project;

  54.     @Override @Nonnull
  55.     public PresentationModel createPresentationModel (@Nonnull final Collection<Object> instanceRoles)
  56.       {
  57.         return PresentationModel.of(project, r(aggregatePresentationModel(), instanceRoles));
  58.       }

  59.     @Nonnull
  60.     protected Aggregate<PresentationModel> aggregatePresentationModel()
  61.       {
  62.         final var budget           = project.getBudget();
  63.         // FIXME: these are dynamically computed, can be slow - should be also cached? Here or in the data objects?
  64.         final var earnings         = project.getEarnings();
  65.         final var invoicedEarnings = project.getInvoicedEarnings();

  66.         // FIXME: uses the column header names, should be an internal id instead
  67.         return PresentationModelAggregate.newInstance()
  68.                 .withPmOf("Client",     r(Displayable.of(((CustomerSpi)project.getCustomer()).getName())))
  69.                 .withPmOf("Status",     r(Displayable.of(project.getStatus().name())))
  70.                 .withPmOf("#",          r(Displayable.of(project::getNumber)))
  71.                 .withPmOf("Name",       r(Displayable.of(project::getName)))
  72.                 .withPmOf("Start Date", r(Displayable.of(DATE_FORMATTER::format, project.getStartDate()),
  73.                                                  RIGHT_ALIGNED))
  74.                 .withPmOf("Due Date",   r(Displayable.of(DATE_FORMATTER::format, project.getEndDate()),
  75.                                                  RIGHT_ALIGNED))
  76.                 .withPmOf("Notes",      r(Displayable.of(project::getNotes)))
  77.                 .withPmOf("Time",       r(Displayable.of(DURATION_FORMATTER::format, project.getDuration()),
  78.                                                  RIGHT_ALIGNED))
  79.                 .withPmOf("Budget",     r(Displayable.of(MONEY_FORMATTER::format, budget),
  80.                       Styleable.of("right-aligned", budget.isEqualTo(Money.ZERO) ? "alerted" : "")))
  81.                 .withPmOf("Earnings",   r(Displayable.of(MONEY_FORMATTER::format, earnings),
  82.                       Styleable.of("right-aligned", earnings.greaterThan(budget) ? "alerted" : "",
  83.                                                     earnings.isEqualTo(budget) ? "green" : "")))
  84.                 .withPmOf("Invoiced",   r(Displayable.of(MONEY_FORMATTER::format, invoicedEarnings),
  85.                       Styleable.of("right-aligned", invoicedEarnings.greaterThan(earnings) ? "alerted" :
  86.                                                     invoicedEarnings.isEqualTo(earnings) ? "green" : "")));
  87.       }
  88.   }